在Spring Security中为自定义过滤器添加身份验证过程

时间:2018-01-30 03:36:12

标签: java spring

现在我的身份验证是使用用户名和密码完成的。我想再添加一个步骤,以便检查用户是否被激活。我有一个用户表,如果用户已激活帐户,则该表保存该值。

我有我的SecurityConfig.java

@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {

        // This somehow works but only if the account is not validated
        // auth.authenticationProvider(new UserActivatedAuthenticationProvider(userService));

        auth.userDetailsService(userDetailsService).passwordEncoder(new ShaPasswordEncoder(encodingStrength));

}

UserActivatedAuthenticationProvider.java

@Component
public class UserActivatedAuthenticationProvider implements AuthenticationProvider {

private final UserService userService;

@Autowired public UserActivatedAuthenticationProvider(UserService userService) {
    this.userService = userService;
}

@Override
public Authentication authenticate(Authentication authentication) throws AuthenticationException {

    String name = authentication.getName();
    User user = userService.findByEmail(name);

    if (user != null) {
        if (!user.isActivated()) {
            throw new BadCredentialsException(name + " email is not activated.");
        }
    }

    Object credentials = authentication.getCredentials();

    if (!(credentials instanceof String)) {
        return null;
    }

    String password = credentials.toString();
    Authentication auth = new UsernamePasswordAuthenticationToken(name, password);

    return auth;
}

@Override
public boolean supports(Class<?> authentication) {
    return authentication.equals(UsernamePasswordAuthenticationToken.class);
}

}

我希望仅在帐户被激活时才进行身份验证。我无法在userService中使用AuthenticationManagerBuilder,因为我无法获取用户名。我使用this project作为种子。简而言之......我还想检查is_activated列的值,并根据现在的值继续进行(用户名和密码验证)。

2 个答案:

答案 0 :(得分:1)

您不需要AuthenticationProvider。您需要实现以下UserDetailsService;

@Service
public class MyUserDetailsService implements UserDetailsService {

    @Autowired
    private UserService userService;

    public UserDetails loadUserByUsername(String username)
                        throws UsernameNotFoundException {
        User user = userService.findByEmail(username);
        if(user == null) {
            throw new UsernameNotFoundException(username);   
        }

        return org.springframework.security.core.userdetails.User(username, user.getPassword(), user.isActivated(), true, true, true, user.getRoles().stream().map(role -> role.getRoleName()).map(SimpleGrantedAuthority::new).collect(Collectors.toList()));

    }
}

spring class org.springframework.security.core.userdetails.User作为名为enabled的属性,您可以从数据库传递user.isActivated()标志。

答案 1 :(得分:1)

您可以通过提供自定义用户详细信息服务来实现此目的。

@Autowired
private CustomUserDetailsService customUserDetailsService ;

@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {    
        auth.userDetailsService(customUserDetailsService ).passwordEncoder(new ShaPasswordEncoder(encodingStrength));

}

@Service
public class CustomUserDetailsService implements UserDetailsService {

    @Autowired
    private UserService userService;

    public UserDetails loadUserByUsername(String username)
                        throws UsernameNotFoundException {
        User user = userService.findByEmail(username);
        if(user == null) {
            throw new UsernameNotFoundException(username);   
        }

            Set<GrantedAuthority> authorities = new HashSet<GrantedAuthority>();        
            GrantedAuthority grantedAuthority = new SimpleGrantedAuthority("USER");
            authorities.add(grantedAuthority);
        return org.springframework.security.core.userdetails.User(username, user.getPassword(), user.isActivated(), true, true, true, authorities );

    }
}

现在基于第三个参数的布尔值,弹簧安全性将自动允许/拒绝用户登录,如果用户未激活,也会给出“禁用用户”消息。