IT评测·应用市场-qidao123.com技术社区

标题: SpringSecurity5(14-Gateway整合) [打印本页]

作者: 傲渊山岳    时间: 2025-4-8 08:16
标题: SpringSecurity5(14-Gateway整合)
MVC 与 WebFlux 关系

SpringSecurity 设置要采用响应式配置,基于 WebFlux 中 WebFilter 实现,与 Spring MVC 的 Security 是通过 Servlet 的 Filter 实现雷同,也是一系列 filter 组成的过滤链。
Reactor 与传统 MVC 配置对应:
webfluxmvc作用@EnableWebFluxSecurity@EnableWebSecurity开启 security 配置ServerAuthenticationSuccessHandlerAuthenticationSuccessHandler登录乐成 HandlerServerAuthenticationFailureHandlerAuthenticationFailureHandler登录失败 HandlerServerLogoutSuccessHandlerLogoutSuccessHandler注销乐成HandlerServerSecurityContextRepositorySecurityContextHolder认证信息存储管理ReactiveUserDetailsServiceUserDetailsService用户登录逻辑处置惩罚ReactiveAuthenticationManagerAuthorizationManager认证管理ReactiveAuthorizationManagerAccessDecisionManager鉴权管理ServerAuthenticationEntryPointAuthenticationEntryPoint未认证 HandlerServerAccessDeniedHandlerAccessDeniedHandler鉴权失败 HandlerAuthenticationWebFilterFilterSecurityInterceptor拦截器快速入门
  1. <dependency>
  2.     <groupId>org.springframework.cloud</groupId>
  3.     <artifactId>spring-cloud-starter-security</artifactId>
  4.     <version>2.2.5.RELEASE</version>
  5. </dependency>
  6. <dependency>
  7.     <groupId>org.springframework.cloud</groupId>
  8.     <artifactId>spring-cloud-starter-gateway</artifactId>
  9.     <version>2.2.6.RELEASE</version>
  10. </dependency>
  11. <dependency>
  12.     <groupId>com.alibaba</groupId>
  13.     <artifactId>fastjson</artifactId>
  14.     <version>2.0.38</version>
  15. </dependency>
  16. <dependency>
  17.     <groupId>org.projectlombok</groupId>
  18.     <artifactId>lombok</artifactId>
  19. </dependency>
复制代码
内存管理用户信息
  1. @EnableWebFluxSecurity
  2. @Configuration
  3. public class SecurityConfig {
  4.     @Bean
  5.     public SecurityWebFilterChain filterChain(ServerHttpSecurity http) {
  6.        http.httpBasic()
  7.                .and()
  8.                .authorizeExchange()
  9.                .anyExchange()
  10.                .authenticated();
  11.         return http.build();
  12.     }
  13.     /**
  14.      * 内存管理用户信息
  15.      */
  16.     @Bean
  17.     public MapReactiveUserDetailsService userDetailsService() {
  18.         UserDetails user = User.withDefaultPasswordEncoder()
  19.                 .username("user")
  20.                 .password("password")
  21.                 .roles("USER")
  22.                 .build();
  23.         return new MapReactiveUserDetailsService(user);
  24.     }
  25. }
复制代码
自定义登录、注销处置惩罚器

  1. @Component
  2. public class LoginSuccessHandler implements ServerAuthenticationSuccessHandler {
  3.     @Override
  4.     public Mono<Void> onAuthenticationSuccess(WebFilterExchange webFilterExchange, Authentication authentication) {
  5.         return Mono.defer(() -> Mono.just(webFilterExchange.getExchange().getResponse()).flatMap(response -> {
  6.             DataBufferFactory dataBufferFactory = response.bufferFactory();
  7.             DataBuffer dataBuffer = dataBufferFactory.wrap("登录成功".getBytes());
  8.             return response.writeWith(Mono.just(dataBuffer));
  9.         }));
  10.     }
  11. }
复制代码
  1. @Component
  2. public class LoginFailHandler implements ServerAuthenticationFailureHandler {
  3.     @Override
  4.     public Mono<Void> onAuthenticationFailure(WebFilterExchange webFilterExchange, AuthenticationException exception) {
  5.         return Mono.defer(() -> Mono.just(webFilterExchange.getExchange().getResponse()).flatMap(response -> {
  6.             DataBufferFactory dataBufferFactory = response.bufferFactory();
  7.             DataBuffer dataBuffer = dataBufferFactory.wrap("登录失败".getBytes());
  8.             return response.writeWith(Mono.just(dataBuffer));
  9.         }));
  10.     }
  11. }
复制代码
  1. @Component
  2. public class LogoutSuccessHandler implements ServerLogoutSuccessHandler {
  3.     @Override
  4.     public Mono<Void> onLogoutSuccess(WebFilterExchange exchange, Authentication authentication) {
  5.         return Mono.defer(() -> Mono.just(exchange.getExchange().getResponse()).flatMap(response -> {
  6.             DataBufferFactory dataBufferFactory = response.bufferFactory();
  7.             DataBuffer dataBuffer = dataBufferFactory.wrap("logout success".getBytes());
  8.             return response.writeWith(Mono.just(dataBuffer));
  9.         }));
  10.     }
  11. }
复制代码
  1. @EnableWebFluxSecurity
  2. @Configuration
  3. public class SecurityConfig {
  4.     @Resource
  5.     private LoginSuccessHandler loginSuccessHandler;
  6.     @Resource
  7.     private LoginFailHandler loginFailHandler;
  8.     @Resource
  9.     private LogoutSuccessHandler logoutSuccessHandler;
  10.     @Bean
  11.     public SecurityWebFilterChain filterChain(ServerHttpSecurity http) {
  12.         http.httpBasic()
  13.                 .and()
  14.                 .authorizeExchange()
  15.                 .anyExchange()
  16.                 .authenticated();
  17.         http.formLogin()
  18.             .authenticationSuccessHandler(loginSuccessHandler)
  19.             .authenticationFailureHandler(loginFailHandler)
  20.             .and()
  21.             .logout()
  22.             .logoutSuccessHandler(logoutSuccessHandler);
  23.         return http.build();
  24.     }
  25.     /**
  26.      * 内存管理用户信息
  27.      */
  28.     @Bean
  29.     public MapReactiveUserDetailsService userDetailsService() {
  30.         UserDetails user = User.withDefaultPasswordEncoder()
  31.                 .username("user")
  32.                 .password("password")
  33.                 .roles("USER")
  34.                 .build();
  35.         return new MapReactiveUserDetailsService(user);
  36.     }
  37. }
复制代码
自定义用户信息

  1. @Component
  2. public class UserDetailService implements ReactiveUserDetailsService, ReactiveUserDetailsPasswordService {
  3.     private final Map<String, UserDetails> users = new HashMap<>();
  4.     @Resource
  5.     private PasswordEncoder passwordEncoder;
  6.     @Override
  7.     public Mono<UserDetails> findByUsername(String username) {
  8.         User user = null;
  9.         if ("user".equals(username)) {
  10.             user = new User("user", passwordEncoder.encode("123456"), true, true, true, true, new ArrayList<>());
  11.         }
  12.         return Mono.justOrEmpty(user);
  13.     }
  14.     @Override
  15.     public Mono<UserDetails> updatePassword(UserDetails user, String newPassword) {
  16.         return Mono.just(user)
  17.                 .map(u ->
  18.                         User.withUserDetails(u)
  19.                                 .password(newPassword)
  20.                                 .build()
  21.                 )
  22.                 .doOnNext(u -> {
  23.                     this.users.put(user.getUsername().toLowerCase(), u);
  24.                 });
  25.     }
  26. }
复制代码
  1. @Component
  2. public class UserAuthenticationManager extends AbstractUserDetailsReactiveAuthenticationManager {
  3.     @Resource
  4.     private PasswordEncoder passwordEncoder;
  5.     @Resource
  6.     private ReactiveUserDetailsService userDetailService;
  7.     @Resource
  8.     private ReactiveUserDetailsPasswordService userDetailsPswService;
  9.     private Scheduler scheduler = Schedulers.boundedElastic();
  10.     private UserDetailsChecker preAuthenticationChecks = user -> {
  11.         if (!user.isAccountNonLocked()) {
  12.             logger.debug("User account is locked");
  13.             throw new LockedException(this.messages.getMessage(
  14.                     "AbstractUserDetailsAuthenticationProvider.locked",
  15.                     "User account is locked"));
  16.         }
  17.         if (!user.isEnabled()) {
  18.             logger.debug("User account is disabled");
  19.             throw new DisabledException(this.messages.getMessage(
  20.                     "AbstractUserDetailsAuthenticationProvider.disabled",
  21.                     "User is disabled"));
  22.         }
  23.         if (!user.isAccountNonExpired()) {
  24.             logger.debug("User account is expired");
  25.             throw new AccountExpiredException(this.messages.getMessage(
  26.                     "AbstractUserDetailsAuthenticationProvider.expired",
  27.                     "User account has expired"));
  28.         }
  29.     };
  30.     private UserDetailsChecker postAuthenticationChecks = user -> {
  31.         if (!user.isCredentialsNonExpired()) {
  32.             logger.debug("User account credentials have expired");
  33.             throw new CredentialsExpiredException(this.messages.getMessage(
  34.                     "AbstractUserDetailsAuthenticationProvider.credentialsExpired",
  35.                     "User credentials have expired"));
  36.         }
  37.     };
  38.     @Override
  39.     public Mono<Authentication> authenticate(Authentication authentication) {
  40.         final String username = authentication.getName();
  41.         final String presentedPassword = (String) authentication.getCredentials();
  42.         return retrieveUser(username)
  43.                 .doOnNext(this.preAuthenticationChecks::check)
  44.                 .publishOn(this.scheduler)
  45.                 .filter(u -> this.passwordEncoder.matches(presentedPassword, u.getPassword()))
  46.                 .switchIfEmpty(Mono.defer(() -> Mono.error(new BadCredentialsException("Invalid Credentials"))))
  47.                 .flatMap(u -> {
  48.                     boolean upgradeEncoding = this.userDetailsPswService != null
  49.                             && this.passwordEncoder.upgradeEncoding(u.getPassword());
  50.                     if (upgradeEncoding) {
  51.                         String newPassword = this.passwordEncoder.encode(presentedPassword);
  52.                         return this.userDetailsPswService.updatePassword(u, newPassword);
  53.                     }
  54.                     return Mono.just(u);
  55.                 })
  56.                 .doOnNext(this.postAuthenticationChecks::check)
  57.                 .map(u -> new UsernamePasswordAuthenticationToken(u, u.getPassword(), u.getAuthorities()) );
  58.     }
  59.     @Override
  60.     protected Mono<UserDetails> retrieveUser(String username) {
  61.         return userDetailService.findBysername(username);
  62.     }
  63. }
复制代码
  1. @EnableWebFluxSecurity
  2. @Configuration
  3. public class SecurityConfig {
  4.     @Resource
  5.     private LoginSuccessHandler loginSuccessHandler;
  6.     @Resource
  7.     private LoginFailHandler loginFailHandler;
  8.     @Resource
  9.     private LogoutSuccessHandler logoutSuccessHandler;
  10.     @Resource
  11.     private UserAuthenticationManager userAuthenticationManager;
  12.     @Bean
  13.     public SecurityWebFilterChain filterChain(ServerHttpSecurity http) {
  14.         http.httpBasic()
  15.                 .and()
  16.                 .authorizeExchange()
  17.                 .anyExchange()
  18.                 .authenticated();
  19.         http.formLogin()
  20.                 .authenticationManager(authenticationManager())
  21.                 .authenticationSuccessHandler(loginSuccessHandler)
  22.                 .authenticationFailureHandler(loginFailHandler)
  23.                                 .and()
  24.                 .logout()
  25.                 .logoutSuccessHandler(logoutSuccessHandler);
  26.         return http.build();
  27.     }
  28.     /**
  29.      * 注册用户信息验证管理器,可按需求添加多个按顺序执行
  30.      */
  31.     @Bean
  32.     public ReactiveAuthenticationManager authenticationManager() {
  33.         LinkedList<ReactiveAuthenticationManager> managers = new LinkedList<>();
  34.         managers.add(userAuthenticationManager);
  35.         return new DelegatingReactiveAuthenticationManager(managers);
  36.     }
  37.     @Bean
  38.     public PasswordEncoder passwordEncoder() {
  39.         return new BCryptPasswordEncoder();
  40.     }
  41. }
复制代码
权限注解
  1. @EnableWebFluxSecurity
  2. @EnableReactiveMethodSecurity
  3. @Configuration
  4. public class SecurityConfig {
  5.         // ....
  6. }
复制代码
  1. @RestController
  2. public class TestController {
  3.     /**
  4.      * 无效
  5.      */
  6.     @Secured({"ROLE_ADMIN"})
  7.     @RequestMapping(value = "/test")
  8.     public Mono<String> test() {
  9.         return Mono.just("test");
  10.     }
  11.     /**
  12.      * 有效
  13.      */
  14.     @PreAuthorize("hasRole('ADMIN')")
  15.     @RequestMapping(value = "/test1")
  16.     public Mono<String> test1() {
  17.         return Mono.just("test1");
  18.     }
  19.     @Secured({"ROLE_TEST"})
  20.     @RequestMapping(value = "/test2")
  21.     public Mono<String> test2() {
  22.         return Mono.just("test2");
  23.     }
  24. }
复制代码
自定义权限处置惩罚器
  1. @Component
  2. public class AccessDeniedHandler implements ServerAccessDeniedHandler {
  3.     @Override
  4.     public Mono<Void> handle(ServerWebExchange exchange, AccessDeniedException denied) {
  5.         return Mono.defer(() -> Mono.just(exchange.getResponse()).flatMap(response -> {
  6.             DataBufferFactory dataBufferFactory = response.bufferFactory();
  7.             DataBuffer dataBuffer = dataBufferFactory.wrap("permission denied".getBytes());
  8.             return response.writeWith(Mono.just(dataBuffer));
  9.         }));
  10.     }
  11. }
复制代码
  1. @EnableWebFluxSecurity
  2. @EnableReactiveMethodSecurity
  3. @Configuration
  4. public class SecurityConfig {
  5.     @Resource
  6.     private LoginSuccessHandler loginSuccessHandler;
  7.     @Resource
  8.     private LoginFailHandler loginFailHandler;
  9.     @Resource
  10.     private LogoutSuccessHandler logoutSuccessHandler;
  11.     @Resource
  12.     private UserAuthenticationManager userAuthenticationManager;
  13.     @Resource
  14.     private AccessDeniedHandler accessDeniedHandler;
  15.     @Bean
  16.     public SecurityWebFilterChain filterChain(ServerHttpSecurity http) {
  17.         http.httpBasic()
  18.                 .and()
  19.                 .authorizeExchange()
  20.                 .anyExchange()
  21.                 .authenticated();
  22.         http.formLogin()
  23.                 .authenticationManager(authenticationManager())
  24.                 .authenticationSuccessHandler(loginSuccessHandler)
  25.                 .authenticationFailureHandler(loginFailHandler)
  26.                 .and()
  27.                 .logout()
  28.                 .logoutSuccessHandler(logoutSuccessHandler)
  29.                 .and()
  30.                 .exceptionHandling()
  31.                 .accessDeniedHandler(accessDeniedHandler);
  32.         return http.build();
  33.     }
  34.     /**
  35.      * 注册用户信息验证管理器,可按需求添加多个按顺序执行
  36.      */
  37.     @Bean
  38.     public ReactiveAuthenticationManager authenticationManager() {
  39.         LinkedList<ReactiveAuthenticationManager> managers = new LinkedList<>();
  40.         managers.add(userAuthenticationManager);
  41.         return new DelegatingReactiveAuthenticationManager(managers);
  42.     }
  43.     @Bean
  44.     public PasswordEncoder passwordEncoder() {
  45.         return new BCryptPasswordEncoder();
  46.     }
  47. }
复制代码
自定义认证处置惩罚器
  1. @Component
  2. public class AuthenticationEntryPoint implements ServerAuthenticationEntryPoint {
  3.     @Override
  4.     public Mono<Void> commence(ServerWebExchange exchange, AuthenticationException e) {
  5.         return Mono.defer(() -> Mono.just(exchange.getResponse()).flatMap(response -> {
  6.             DataBufferFactory dataBufferFactory = response.bufferFactory();
  7.             DataBuffer dataBuffer = dataBufferFactory.wrap("Authentication fail".getBytes());
  8.             return response.writeWith(Mono.just(dataBuffer));
  9.         }));
  10.     }
  11. }
复制代码
  1. @EnableWebFluxSecurity
  2. @EnableReactiveMethodSecurity
  3. @Configuration
  4. public class SecurityConfig {
  5.     @Resource
  6.     private LoginSuccessHandler loginSuccessHandler;
  7.     @Resource
  8.     private LoginFailHandler loginFailHandler;
  9.     @Resource
  10.     private LogoutSuccessHandler logoutSuccessHandler;
  11.     @Resource
  12.     private UserAuthenticationManager userAuthenticationManager;
  13.     @Resource
  14.     private AccessDeniedHandler accessDeniedHandler;
  15.     @Resource
  16.     private AuthenticationEntryPoint authenticationEntryPoint;
  17.     @Bean
  18.     public SecurityWebFilterChain filterChain(ServerHttpSecurity http) {
  19.         http.httpBasic()
  20.                 .and()
  21.                 .authorizeExchange()
  22.                 .anyExchange()
  23.                 .authenticated();
  24.         http.formLogin()
  25.                 .authenticationManager(authenticationManager())
  26.                 .authenticationSuccessHandler(loginSuccessHandler)
  27.                 .authenticationFailureHandler(loginFailHandler)
  28.                 .and()
  29.                 .logout()
  30.                 .logoutSuccessHandler(logoutSuccessHandler)
  31.                 .and()
  32.                 .exceptionHandling()
  33.                 .accessDeniedHandler(accessDeniedHandler)
  34.                 .authenticationEntryPoint(authenticationEntryPoint);
  35.         return http.build();
  36.     }
  37.     /**
  38.      * 注册用户信息验证管理器,可按需求添加多个按顺序执行
  39.      */
  40.     @Bean
  41.     public ReactiveAuthenticationManager authenticationManager() {
  42.         LinkedList<ReactiveAuthenticationManager> managers = new LinkedList<>();
  43.         managers.add(userAuthenticationManager);
  44.         return new DelegatingReactiveAuthenticationManager(managers);
  45.     }
  46.     @Bean
  47.     public PasswordEncoder passwordEncoder() {
  48.         return new BCryptPasswordEncoder();
  49.     }
  50. }
复制代码
自定义鉴权处置惩罚器

[code]@Slf4j@Componentpublic class AuthorizeConfigManager implements ReactiveAuthorizationManager {    private final AntPathMatcher antPathMatcher = new AntPathMatcher();    @Override    public Mono check(Mono authentication,                                             AuthorizationContext authorizationContext) {        return authentication.map(auth -> {            ServerWebExchange exchange = authorizationContext.getExchange();            ServerHttpRequest request = exchange.getRequest();            Collection




欢迎光临 IT评测·应用市场-qidao123.com技术社区 (https://dis.qidao123.com/) Powered by Discuz! X3.4