【问题标题】:Spring security manually authentication not workingSpring Security手动身份验证不起作用
【发布时间】:2019-07-18 10:24:26
【问题描述】:

我正在使用 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 没有更新身份验证,因此用户始终是匿名的。

【问题讨论】:

  • token 是否在 authenticate 方法中正确创建?
  • 如果要到达 /authenticate 端点,用户将如何进行身份验证?
  • 嗨 Andronicus,是的 token 是在 authenticate 方法中正确创建的,SecurityContext 已成功更新,但是当我尝试访问其他方法时,spring 返回 403 错误。
  • 嗨 NatFar,在 SecurityConfig 类中,我为 URL "/login/api/**" 创建了一个带有 permitAll 的 antMatcher,方法 authenticate 是具有该 URL 的控制器的一部分

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


【解决方案1】:

我找到了问题的解决方案,我更改了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();
}

上一个配置有问题,permitAll 方法和authenticated 方法用于anyRequest,按此顺序更改not().authenticated()not().anonymous() 的配置,我得到了预期的结果。

【讨论】:

    猜你喜欢
    • 2017-02-13
    • 2011-11-14
    • 2021-04-06
    • 2015-08-27
    • 2014-01-28
    • 1970-01-01
    • 2014-07-29
    • 2017-05-10
    相关资源
    最近更新 更多