ServerAuthenticationSuccessHandler这个类的onAuthenticationSuccess方法的作用是什么?

onAuthenticationSuccess方法是ServerAuthenticationSuccessHandler接口的一部分,它在Spring Security中用于处理认证成功后的逻辑。当用户成功通过认证时,这个方法会被调用。

在Spring Security的WebFlux环境中,认证过程是由一系列的过滤器(Filters)来处理的。这些过滤器构成了一个过滤器链,每个过滤器都有特定的职责。在认证过程中,AuthenticationWebFilter是负责处理认证逻辑的过滤器。当用户提交了登录信息(如用户名和密码),并且这些信息被验证为正确时,AuthenticationWebFilter会生成一个Authentication对象,并将其标记为已认证。

AuthenticationWebFilter会使用一个ServerAuthenticationSuccessHandler来处理认证成功后的逻辑。Oauth2AuthSuccessHandler类实现了ServerAuthenticationSuccessHandler接口,因此它的onAuthenticationSuccess方法会在AuthenticationWebFilter确认用户成功认证后被调用。

onAuthenticationSuccess方法中,可以执行一些自定义的逻辑,例如添加自定义的HTTP头、重定向到另一个页面、更新用户的登录信息等。在Oauth2AuthSuccessHandler的实现中,它主要是用来添加一些自定义的HTTP头到响应中,这些头包含了用户的信息,如用户ID、用户名、用户类型和用户详细信息。这些信息被添加到HTTP头中,以便后续的请求可以使用这些信息进行进一步的处理。

onAuthenticationSuccess方法的最后,通过调用webFilterExchange.getChain().filter(build),将修改后的ServerWebExchange传递回过滤器链,以便继续处理后续的过滤器逻辑。

总结来说,onAuthenticationSuccess方法是在用户成功认证后由AuthenticationWebFilter调用的,用于执行认证成功后的自定义逻辑,并且它是Spring Security的WebFlux支持中的一部分。

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
好的,下面是SpringCloud Gateway 集成SpringSecurity 的代码示例: ### 1.添加依赖 在pom.xml文件中添加以下依赖: ```xml <dependencies> <!-- Spring Cloud Gateway --> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-gateway</artifactId> </dependency> <!-- Spring Security --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-security</artifactId> </dependency> </dependencies> ``` ### 2.配置Spring Security 在WebSecurityConfigurerAdapter中配置Spring Security,如下所示: ```java @Configuration @EnableWebFluxSecurity public class SecurityConfig { @Bean public SecurityWebFilterChain securityWebFilterChain(ServerHttpSecurity http) { http.authorizeExchange() .pathMatchers("/auth/**").permitAll() .pathMatchers(HttpMethod.OPTIONS).permitAll() .anyExchange().authenticated() .and() .httpBasic().and() .formLogin(); return http.build(); } @Bean public PasswordEncoder passwordEncoder() { return PasswordEncoderFactories.createDelegatingPasswordEncoder(); } } ``` 上述代码中,我们配置了一个SecurityWebFilterChain,用于授权和认证请求。 其中,我们允许/auth/**下的所有请求不需要认证,OPTIONS请求也不需要认证。其他请求都需要进行认证。 ### 3.配置Gateway 在Gateway中配置Spring Security,如下所示: ```java @Configuration public class GatewayConfig { @Autowired private AuthenticationManager authenticationManager; @Bean public SecurityWebFilterChain securityWebFilterChain(ServerHttpSecurity http) { http.authorizeExchange() .pathMatchers("/auth/**").permitAll() .pathMatchers(HttpMethod.OPTIONS).permitAll() .anyExchange().authenticated() .and() .httpBasic().and() .formLogin(); return http.build(); } @Bean public ReactiveAuthenticationManager reactiveAuthenticationManager() { UserDetailsRepositoryReactiveAuthenticationManager authenticationManager = new UserDetailsRepositoryReactiveAuthenticationManager(userDetailsService()); authenticationManager.setPasswordEncoder(passwordEncoder()); return authenticationManager; } @Bean public ReactiveUserDetailsService userDetailsService() { return new MapReactiveUserDetailsService( User.withUsername("user") .password(passwordEncoder().encode("password")) .roles("USER") .build() ); } @Bean public PasswordEncoder passwordEncoder() { return PasswordEncoderFactories.createDelegatingPasswordEncoder(); } @Bean public SecurityContextRepository securityContextRepository() { return new WebSessionServerSecurityContextRepository(); } @Bean public ServerAuthenticationSuccessHandler serverAuthenticationSuccessHandler() { return new RedirectServerAuthenticationSuccessHandler("/index"); } @Bean public ServerAuthenticationFailureHandler serverAuthenticationFailureHandler() { return new RedirectServerAuthenticationFailureHandler("/login?error"); } @Bean public ServerLogoutSuccessHandler serverLogoutSuccessHandler() { return new RedirectServerLogoutSuccessHandler("/login"); } @Bean public ServerSecurityContextRepository serverSecurityContextRepository() { return new WebSessionServerSecurityContextRepository(); } @Bean public SecurityWebFilterChain springSecurityFilterChain(ServerHttpSecurity http) { http .csrf().disable() .httpBasic().disable() .formLogin().disable() .logout().disable() .authenticationManager(authenticationManager) .securityContextRepository(securityContextRepository()) .authorizeExchange() .pathMatchers("/auth/**").permitAll() .anyExchange().authenticated() .and().exceptionHandling() .authenticationEntryPoint(new HttpStatusServerEntryPoint(HttpStatus.UNAUTHORIZED)) .accessDeniedHandler(new HttpStatusServerAccessDeniedHandler(HttpStatus.FORBIDDEN)) .and().addFilterAt(new AuthenticationWebFilter(reactiveAuthenticationManager()), SecurityWebFiltersOrder.AUTHENTICATION) .addFilterAt(new SecurityContextServerWebExchangeConfigurer(serverSecurityContextRepository()), SecurityWebFiltersOrder.SECURITY_CONTEXT) .addFilterAt(new LogoutWebFilter(serverLogoutSuccessHandler()), SecurityWebFiltersOrder.LOGOUT) .addFilterAt(new GatewayAuthFilter(), SecurityWebFiltersOrder.AUTHENTICATION) .addFilterAt(new GatewayRateLimitFilter(), SecurityWebFiltersOrder.AUTHENTICATION); return http.build(); } } ``` 上述代码中,我们配置了一个GatewayAuthFilter,用于验证请求的token是否有效,以及一个GatewayRateLimitFilter,用于限流。 ### 4.编写GatewayAuthFilter 在GatewayAuthFilter中编写登录鉴权逻辑,如下所示: ```java @Component public class GatewayAuthFilter extends OncePerRequestFilter { private static final String JWT_SECRET = "secret"; private static final long JWT_EXPIRE_TIME = 3600 * 1000; // 1 hour @Override protected void doFilterInternal(ServerHttpRequest request, ServerHttpResponse response, FilterChain filterChain) throws ServletException, IOException { String token = request.getHeaders().getFirst("Authorization"); if (StringUtils.isNotEmpty(token) && token.startsWith("Bearer ")) { token = token.substring(7); try { Jws<Claims> jwt = Jwts.parser().setSigningKey(JWT_SECRET).parseClaimsJws(token); Claims claims = jwt.getBody(); String username = claims.getSubject(); if (StringUtils.isNotEmpty(username)) { List<String> authorities = (List<String>) claims.get("authorities"); UsernamePasswordAuthenticationToken authenticationToken = new UsernamePasswordAuthenticationToken(username, null, authorities.stream().map(SimpleGrantedAuthority::new).collect(Collectors.toList())); SecurityContextHolder.getContext().setAuthentication(authenticationToken); } } catch (Exception e) { // ignore } } filterChain.doFilter(request, response); } public static String generateToken(String username, List<String> authorities) { long now = System.currentTimeMillis(); return Jwts.builder() .setSubject(username) .claim("authorities", authorities) .setIssuedAt(new Date(now)) .setExpiration(new Date(now + JWT_EXPIRE_TIME)) .signWith(SignatureAlgorithm.HS512, JWT_SECRET) .compact(); } } ``` 上述代码中,我们编写了一个GatewayAuthFilter,用于验证请求的token是否有效。如果token有效,则设置用户的权限信息,并将用户信息保存在SecurityContextHolder中。 ### 5.编写GatewayRateLimitFilter 在GatewayRateLimitFilter中编写限流逻辑,如下所示: ```java @Component public class GatewayRateLimitFilter extends AbstractGatewayFilterFactory<GatewayRateLimitFilter.Config> { private final RateLimiter rateLimiter; public GatewayRateLimitFilter(RateLimiter rateLimiter) { super(Config.class); this.rateLimiter = rateLimiter; } @Override public GatewayFilter apply(Config config) { return (exchange, chain) -> { if (!rateLimiter.tryAcquire()) { exchange.getResponse().setStatusCode(HttpStatus.TOO_MANY_REQUESTS); return exchange.getResponse().setComplete(); } return chain.filter(exchange); }; } public static class Config { } } ``` 上述代码中,我们编写了一个GatewayRateLimitFilter,用于限流。我们使用了Google的Guava库中的RateLimiter进行限流。 ### 6.测试 现在,我们已经完成了SpringCloud Gateway 集成SpringSecurity 的代码编写。我们可以启动应用程序并进行测试。首先,我们需要生成一个token,然后将其添加到Authorization头中,如下所示: ```bash curl -X POST -d "username=user&password=password" http://localhost:8080/auth/login # {"token":"eyJhbGciOiJIUzUxMiJ9.eyJzdWIiOiJ1c2VyIiwidXNlcl9uYW1lIjoidXNlciIsImF1dGhvcml0aWVzIjpbIlVTRVIiXSwiaWF0IjoxNjIzMjU4NTM5LCJleHAiOjE2MjMyNjI5MzksImp0aSI6ImM2YjMxYjU2LWY5ZjktNDIwOS04ZjU1LWYyY2E3ZjkwMWYxYyJ9.C9y2vBZ5qM0C2xL8lG24Lj5r5y-1o6wHqxJlC6BhYt8L4jZr2WJWvZb5vz7VQZbC7H7t0l2SJRn9y5kYJ4IBw"} ``` 然后,我们可以测试请求,如下所示: ```bash curl -H "Authorization: Bearer eyJhbGciOiJIUzUxMiJ9.eyJzdWIiOiJ1c2VyIiwidXNlcl9uYW1lIjoidXNlciIsImF1dGhvcml0aWVzIjpbIlVTRVIiXSwiaWF0IjoxNjIzMjU4NTM5LCJleHAiOjE2MjMyNjI5MzksImp0aSI6ImM2YjMxYjU2LWY5ZjktNDIwOS04ZjU1LWYyY2E3ZjkwMWYxYyJ9.C9y2vBZ5qM0C2xL8lG24Lj5r5y-1o6wHqxJlC6BhYt8L4jZr2WJWvZb5vz7VQZbC7H7t0l2SJRn9y5kYJ4IBw" http://localhost:8080/hello ``` 如果请求成功,则可以看到返回的结果。如果请求失败,则可以看到错误信息。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值