Статьи

Spring Security и пользовательские пароли

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

Однако в случае пользовательских UserDetailsServices нам нужно внести некоторые изменения в нашу конфигурацию безопасности.
Нам нужно создать компонент DaoAuthenticationProvider и установить для него AuthenticationManagerBuilder.

Так как нам нужен Custom UserDetailsService, я буду использовать пример кода базы Spring Security / MongoDB .

Что нам нужно сделать, это изменить нашу конфигурацию 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
45
46
47
48
49
50
51
52
53
54
55
56
57
58
package com.gkatzioura.spring.security.config;
 
import com.gkatzioura.spring.security.service.CustomerUserDetailsService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Profile;
import org.springframework.security.authentication.dao.DaoAuthenticationProvider;
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 org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
 
import javax.sql.DataSource;
 
/**
 * Created by gkatzioura on 10/5/16.
 */
@EnableWebSecurity
@Profile("encodedcustompassword")
public class PasswordCustomEncodedSecurityConfig extends WebSecurityConfigurerAdapter {
 
    @Bean
    public UserDetailsService mongoUserDetails() {
        return new CustomerUserDetailsService();
    }
 
    @Bean
    public DaoAuthenticationProvider authProvider() {
        DaoAuthenticationProvider authProvider = new DaoAuthenticationProvider();
        authProvider.setUserDetailsService(mongoUserDetails());
        authProvider.setPasswordEncoder(new BCryptPasswordEncoder());
        return authProvider;
    }
 
    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
 
        auth.authenticationProvider(authProvider());
    }
 
    @Override
    protected void configure(HttpSecurity http) throws Exception {
 
        http.authorizeRequests()
                .antMatchers("/public").permitAll()
                .anyRequest().authenticated()
                .and()
                .formLogin()
                .permitAll()
                .and()
                .logout()
                .permitAll();
    }
 
}

В большинстве случаев это работает нормально. Однако мы могли бы также захотеть свернуть наш собственный PasswordEncoder, что довольно легко.

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
package com.gkatzioura.spring.security.encoder;
 
import org.springframework.security.crypto.bcrypt.BCrypt;
import org.springframework.security.crypto.password.PasswordEncoder;
 
/**
 * Created by gkatzioura on 10/5/16.
 */
public class CustomPasswordEncoder implements PasswordEncoder {
 
    @Override
    public String encode(CharSequence rawPassword) {
 
        String hashed = BCrypt.hashpw(rawPassword.toString(), BCrypt.gensalt(12));
 
        return hashed;
    }
 
    @Override
    public boolean matches(CharSequence rawPassword, String encodedPassword) {
 
        return BCrypt.checkpw(rawPassword.toString(), encodedPassword);
    }
 
}

Поэтому мы изменим нашу конфигурацию, чтобы использовать новый PasswordEncoder

1
2
3
4
5
6
7
@Bean
    public DaoAuthenticationProvider authProvider() {
        DaoAuthenticationProvider authProvider = new DaoAuthenticationProvider();
        authProvider.setUserDetailsService(mongoUserDetails());
        authProvider.setPasswordEncoder(new CustomPasswordEncoder());
        return authProvider;
    }

Следующим шагом будет создание закодированного пароля.

1
2
3
4
5
6
7
8
@Test
    public void customEncoder() {
 
        CustomPasswordEncoder customPasswordEncoder = new CustomPasswordEncoder();
        String encoded = customPasswordEncoder.encode("custom_pass");
 
        LOGGER.info("Custom encoded "+encoded);
    }

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

1
db.users.insert({"name":"John","surname":"doe","email":"john2@doe.com","password":"$2a$12$qB.L7buUPi2RJHZ9fYceQ.XdyEFxjAmiekH9AEkJvh1gLFPGEf9mW","authorities":["user","admin"]})

Все, что нам нужно, это изменить профиль по умолчанию в нашем скрипте gradle, и мы готовы к работе.

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

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