【发布时间】: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