Spring Security手动身份验证不起作用

时间:2019-02-25 03:16:55

标签: spring spring-boot spring-mvc spring-security

我正在使用Spring Boot更改现有应用程序,此应用程序未使用Spring Security进行身份验证,身份验证是控制器中的一种方法,因此我想使用Spring Security,并且尝试在Spring Security中手动使用身份验证但不起作用,您可以在下面看到以下代码:

控制器:

@Autowired
@Qualifier(BeanIds.AUTHENTICATION_MANAGER)
private AuthenticationManager authenticationManager;

@PostMapping(value = "/authenticate")
public ResponseEntity<UsuarioRequest> login(@RequestBody UsuarioRequest request, HttpServletRequest servletRequest)
        throws AppException {
    UsernamePasswordAuthenticationToken authToken = new UsernamePasswordAuthenticationToken(request.getUsulog(), request.getUsupass());
    Authentication authentication = authenticationManager
            .authenticate(authToken);
    SecurityContext context = SecurityContextHolder.getContext();
    context.setAuthentication(authentication);
    UsuarioRequest usuario = usuarioFacadeAPI.findByUsername(request.getUsulog());
    return new ResponseEntity<UsuarioRequest>(usuario, HttpStatus.OK);
}

安全配置:

@Configuration
@EnableWebSecurity
@EnableGlobalMethodSecurity(prePostEnabled = true, securedEnabled = true)
public class SecurityConfig extends WebSecurityConfigurerAdapter {

private SiscoAuthenticationProvider siscoAuthenticationProvider;

@Autowired
public SecurityConfig(SiscoAuthenticationProvider siscoAuthenticationProvider) {
    super();
    this.siscoAuthenticationProvider = siscoAuthenticationProvider;
}

@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
    auth.authenticationProvider(siscoAuthenticationProvider);
}

@Override
protected void configure(HttpSecurity http) throws Exception {
    http.formLogin().disable();
    http.csrf().disable();
    http.authenticationProvider(siscoAuthenticationProvider).authorizeRequests() 
            .antMatchers("/login/api/**", "/zona/api/**", "/rol/api/**").permitAll()
            .anyRequest().authenticated();
}


@Bean(name = BeanIds.AUTHENTICATION_MANAGER)
@Override
protected AuthenticationManager authenticationManager() throws Exception {
    return super.authenticationManager();
}

}

CustomAuthenticationProvider:

@Component
public class SiscoAuthenticationProvider implements AuthenticationProvider{

private static final String ROLE = "ROLE_";
@Autowired
private UsuarioServiceAPI usuarioServiceAPI;

@Override
public Authentication authenticate(Authentication authentication) throws AuthenticationException {
    UsernamePasswordAuthenticationToken token = null;
    try {
        UsuarioRequest request = usuarioServiceAPI.authenticate(authentication.getPrincipal().toString(), authentication.getCredentials().toString());
        List<RolRequest> rols = request.getRoles();
        List<SimpleGrantedAuthority> authorities = new ArrayList<>();
        for (RolRequest rol : rols) {
            authorities.add(new SimpleGrantedAuthority(ROLE+rol.getRolnom()));
        }
        token = new UsernamePasswordAuthenticationToken(authentication.getPrincipal(), authentication.getCredentials(), authorities);
    } catch (AppException e) {
        String message = BundleLoader.getMessage(e.getDetails().getBundle(), e.getDetails().getKey(),
                LocaleContextHolder.getLocale());
        throw new UsernameNotFoundException(message, e);
    }
    return token;
}

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

}

对于permitAll配置,没有问题,但是即使在身份验证成功之后,任何其他请求也返回403错误代码,我怀疑在控制器中SecurityContextHolder无法更新身份验证,由此用户始终是匿名的。

1 个答案:

答案 0 :(得分:0)

我找到了解决问题的方法,我更改了Spring Security Config类,特别是下面的方法configure(HttpSecurity http)代码:

@Override
protected void configure(HttpSecurity http) throws Exception {
    http.formLogin().disable();
    http.csrf().disable();

   http.authenticationProvider(siscoAuthenticationProvider).authorizeRequests() 
            .antMatchers("/login/api/**", "/zona/api/**", "/rol/api/**").not().authenticated()
            .anyRequest().not().anonymous();
}

prev配置存在问题,对于anyRequest使用permitAll方法和authenticated方法,依次更改not().authenticated()not().anonymous()的配置,我得到了预期结果。