Nor*_*alo 9 java authentication spring spring-mvc spring-security
我正在尝试使用最新版本的Spring Boot,Web和Security实现自定义身份验证逻辑,但我正在努力解决一些问题.我在类似的问题/教程中尝试了许多解决方案但没有成功或理解实际发生的事情.
我正在创建一个具有无状态身份验证的REST应用程序,即有一个REST端点(/ web/auth/login)需要用户名和密码并返回一个字符串标记,然后在所有其他REST端点中使用(/ api/**)识别用户.我需要实现自定义解决方案,因为将来身份验证将变得更加复杂,我想了解Spring Security的基础知识.
为了实现令牌认证,我正在创建一个自定义过滤器和提供者:
过滤器:
public class TokenAuthenticationFilter extends AbstractAuthenticationProcessingFilter {
public TokenAuthenticationFilter() {
super(new AntPathRequestMatcher("/api/**", "GET"));
}
@Override
public Authentication attemptAuthentication(HttpServletRequest request, HttpServletResponse response) throws AuthenticationException, IOException, ServletException {
String token = request.getParameter("token");
if (token == null || token.length() == 0) {
throw new BadCredentialsException("Missing token");
}
UsernamePasswordAuthenticationToken authenticationToken = new UsernamePasswordAuthenticationToken(token, null);
return getAuthenticationManager().authenticate(authenticationToken);
}
}
Run Code Online (Sandbox Code Playgroud)
提供者:
@Component
public class TokenAuthenticationProvider implements AuthenticationProvider {
@Autowired
private AuthenticationTokenManager tokenManager;
@Override
public Authentication authenticate(Authentication authentication) throws AuthenticationException {
String token = (String)authentication.getPrincipal();
return tokenManager.getAuthenticationByToken(token);
}
@Override
public boolean supports(Class<?> authentication) {
return UsernamePasswordAuthenticationToken.class.equals(authentication);
}
}
Run Code Online (Sandbox Code Playgroud)
配置:
@EnableWebSecurity
@Order(1)
public class TokenAuthenticationSecurityConfig extends WebSecurityConfigurerAdapter {
@Autowired
private TokenAuthenticationProvider authProvider;
@Override
protected void configure(HttpSecurity http) throws Exception {
http.antMatcher("/api/**")
.csrf().disable()
.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS)
.and().addFilterBefore(authenticationFilter(), BasicAuthenticationFilter.class);
}
@Bean
public TokenAuthenticationFilter authenticationFilter() throws Exception {
TokenAuthenticationFilter tokenProcessingFilter = new TokenAuthenticationFilter();
tokenProcessingFilter.setAuthenticationManager(authenticationManager());
return tokenProcessingFilter;
}
@Override
public void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.authenticationProvider(authProvider);
}
}
Run Code Online (Sandbox Code Playgroud)
提供程序中使用的AuthenticationTokenManager(以及登录过程中):
@Component
public class AuthenticationTokenManager {
private Map<String, AuthenticationToken> tokens;
public AuthenticationTokenManager() {
tokens = new HashMap<>();
}
private String generateToken(AuthenticationToken authentication) {
return UUID.randomUUID().toString();
}
public String addAuthentication(AuthenticationToken authentication) {
String token = generateToken(authentication);
tokens.put(token, authentication);
return token;
}
public AuthenticationToken getAuthenticationByToken(String token) {
return tokens.get(token);
}
Run Code Online (Sandbox Code Playgroud)
}
会发生什么: 我将请求中的有效令牌附加到"/ api/bla"(这是一个REST控制器返回一些Json).调用过滤器和提供程序.问题是,浏览器被重定向到"/"而不是调用REST控制器的请求方法.这似乎发生在SavedRequestAwareAuthenticationSuccessHandler中,但为什么要使用这个处理程序?
我试过了
我想了解为什么我在验证令牌后没有调用我的控制器.除此之外,是否存在一种"Spring"方式来存储令牌而不是将其存储在Map中,就像SecurityContextRepository的自定义实现一样?
我真的很感激任何暗示!
小智 4
可能有点晚了,但我遇到了同样的问题并添加:
@Override
protected void successfulAuthentication(
final HttpServletRequest request, final HttpServletResponse response,
final FilterChain chain, final Authentication authResult)
throws IOException, ServletException {
chain.doFilter(request, response);
}
Run Code Online (Sandbox Code Playgroud)
我的 AbstractAuthenticationProcessingFilter 实现成功了。
归档时间: |
|
查看次数: |
2136 次 |
最近记录: |