Статьи

Spring Security и шифрование паролей

На предыдущих постах мы погрузились в весеннюю безопасность. Мы реализовали защиту, поддерживаемую jdbc , защиту на основе пользовательских запросов jdbc и защиту, получающую информацию из базы данных nosql .

Будучи достаточно осторожными, мы обнаружим, что пароли в текстовом виде. Хотя это хорошо подходит для примера в реальных условиях, пароли всегда кодируются и хранятся в базе данных.

Spring security поддерживает кодирование пароля довольно удобным способом. Он поставляется с собственными предварительно сконфигурированными кодировщиками паролей, но также дает нам возможность либо создать наш собственный кодировщик паролей.

StandardPasswordEncoder, Md5PasswordEncoder и популярный BCryptPasswordEncoder являются одними из кодировщиков паролей, которые поставляются вместе с Spring Security.

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
package com.gkatzioura.spring.security;
 
import org.junit.Test;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.security.authentication.encoding.Md5PasswordEncoder;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.StandardPasswordEncoder;
 
/**
 * Created by gkatzioura on 10/5/16.
 */
public class EncoderTest {
 
    private static final Logger LOGGER = LoggerFactory.getLogger(EncoderTest.class);
 
    @Test
    public void md5Encoder() {
 
        Md5PasswordEncoder md5PasswordEncoder = new Md5PasswordEncoder();
        String encoded = md5PasswordEncoder.encodePassword("test_pass",null);
 
        LOGGER.info("Md5 encoded "+encoded);
    }
 
    @Test
    public void bcryptEncoder() {
 
        BCryptPasswordEncoder bCryptPasswordEncoder = new BCryptPasswordEncoder();
        String encoded = bCryptPasswordEncoder.encode("test_pass");
 
        LOGGER.info("Becrypt encoded "+encoded);
    }
 
    @Test
    public void standardEncoder() {
 
        StandardPasswordEncoder standardPasswordEncoder = new StandardPasswordEncoder();
        String encoded = standardPasswordEncoder.encode("test_pass");
 
        LOGGER.info("Standard encoded "+encoded);
    }
 
}

Чтобы добавить кодировку пароля, все что нам нужно сделать, это установить кодировщик пароля в нашей весенней конфигурации.

С помощью пружинной конфигурации безопасности с поддержкой jdbc это довольно просто, мы просто устанавливаем кодировщик пароля по своему выбору. В нашем случае мы будем использовать кодировщик паролей md5.

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
package com.gkatzioura.spring.security.config;
 
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Profile;
import org.springframework.security.authentication.encoding.Md5PasswordEncoder;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
 
import javax.sql.DataSource;
 
/**
 * Created by gkatzioura on 10/5/16.
 */
@EnableWebSecurity
@Profile("encodedjdbcpassword")
public class PasswordEncodedSecurityConfig extends WebSecurityConfigurerAdapter {
 
    @Autowired
    private DataSource dataSource;
 
    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
 
        auth.jdbcAuthentication().dataSource(dataSource)
                .passwordEncoder(new Md5PasswordEncoder())
                .usersByUsernameQuery("SELECT username,password,1 FROM Custom_Users_Encoded_pass where username=?")
                .authoritiesByUsernameQuery("SELECT username,authority FROM Custom_Roles where username=?");
    }
 
    @Override
    protected void configure(HttpSecurity http) throws Exception {
 
        http.authorizeRequests()
                .antMatchers("/public").permitAll()
                .anyRequest().authenticated()
                .and()
                .formLogin()
                .permitAll()
                .and()
                .logout()
                .permitAll();
    }
 
}

Затем мы добавим пользователя в базу данных с зашифрованным паролем.

1
2
3
4
drop table if exists Custom_Users_Encoded_pass;
create table Custom_Users_Encoded_pass(id bigint auto_increment, username varchar(255), password varchar(255));
-- real password is test_pass
insert into Custom_Users_Encoded_pass(username,password) values('TestUser','4ac1b63dca561d274c6055ebf3ed97db');

Поэтому при попытке доступа к http: // localhost: 8080 / secure будет необходимо указать имя пользователя TestUser и пароль test_pass в приглашении для входа.

И последнее, но не менее важное: нам нужно изменить наш gradle.build, чтобы установить кодированный jdbcpassword в качестве нашего профиля по умолчанию.

1
2
3
bootRun {
    systemProperty "spring.profiles.active", "encodedjdbcpassword"
}

Вы можете найти исходный код на github .

Ссылка: Spring Security и Password Encoding от нашего партнера JCG Эммануила Гкатциоураса в блоге gkatzioura .