spring security webflux 自定义登录页面


spring security webflux 自定义登录页面


 

*************************

相关类及接口

 

ServerHttpSecurity

public class ServerHttpSecurity {


******************
内部类:ServerHttpSecurity.FormLoginSpec

    public class FormLoginSpec {
        private final RedirectServerAuthenticationSuccessHandler defaultSuccessHandler;
        private RedirectServerAuthenticationEntryPoint defaultEntryPoint;
        private ReactiveAuthenticationManager authenticationManager;
        private ServerSecurityContextRepository securityContextRepository;
        private ServerAuthenticationEntryPoint authenticationEntryPoint;       //认证端口,如果不设置,默认:RedirectServerAuthenticationEntryPoint("/login")
        private boolean isEntryPointExplicit;
        private ServerWebExchangeMatcher requiresAuthenticationMatcher;        //设置自定义的认证路径,默认与loginPage相同
        private ServerAuthenticationFailureHandler authenticationFailureHandler;
        private ServerAuthenticationSuccessHandler authenticationSuccessHandler;

        public ServerHttpSecurity.FormLoginSpec authenticationManager(ReactiveAuthenticationManager authenticationManager) {
            this.authenticationManager = authenticationManager;
            return this;
        }

        public ServerHttpSecurity.FormLoginSpec authenticationSuccessHandler(ServerAuthenticationSuccessHandler authenticationSuccessHandler) {
            Assert.notNull(authenticationSuccessHandler, "authenticationSuccessHandler cannot be null");
            this.authenticationSuccessHandler = authenticationSuccessHandler;
            return this;
        }

        public ServerHttpSecurity.FormLoginSpec loginPage(String loginPage) {
            this.defaultEntryPoint = new RedirectServerAuthenticationEntryPoint(loginPage);
            this.authenticationEntryPoint = this.defaultEntryPoint;  //设置默认的认证端口
            if (this.requiresAuthenticationMatcher == null) {
                this.requiresAuthenticationMatcher = ServerWebExchangeMatchers.pathMatchers(HttpMethod.POST, new String[]{loginPage});
            }                                                       //认证方式默认为post、路径为:/loginPage

            if (this.authenticationFailureHandler == null) {
                this.authenticationFailureHandler = new RedirectServerAuthenticationFailureHandler(loginPage + "?error");
            }

            return this;
        }

        public ServerHttpSecurity.FormLoginSpec authenticationEntryPoint(ServerAuthenticationEntryPoint authenticationEntryPoint) {
            this.authenticationEntryPoint = authenticationEntryPoint;
            return this;
        }

        public ServerHttpSecurity.FormLoginSpec requiresAuthenticationMatcher(ServerWebExchangeMatcher requiresAuthenticationMatcher) {
            this.requiresAuthenticationMatcher = requiresAuthenticationMatcher;
            return this;
        }

        public ServerHttpSecurity.FormLoginSpec authenticationFailureHandler(ServerAuthenticationFailureHandler authenticationFailureHandler) {
            this.authenticationFailureHandler = authenticationFailureHandler;
            return this;
        }

        public ServerHttpSecurity.FormLoginSpec securityContextRepository(ServerSecurityContextRepository securityContextRepository) {
            this.securityContextRepository = securityContextRepository;
            return this;
        }

        public ServerHttpSecurity and() {
            return ServerHttpSecurity.this;
        }

        public ServerHttpSecurity disable() {
            ServerHttpSecurity.this.formLogin = null;
            return ServerHttpSecurity.this;
        }

        protected void configure(ServerHttpSecurity http) {
            if (this.authenticationEntryPoint == null) {
                this.isEntryPointExplicit = false;
                this.loginPage("/login");          //如果authenticationEntryPoint为null,loginPage默认为:/login
            } else {
                this.isEntryPointExplicit = true;
            }

            if (http.requestCache != null) {
                ServerRequestCache requestCache = http.requestCache.requestCache;
                this.defaultSuccessHandler.setRequestCache(requestCache);
                if (this.defaultEntryPoint != null) {
                    this.defaultEntryPoint.setRequestCache(requestCache);
                }
            }

            MediaTypeServerWebExchangeMatcher htmlMatcher = new MediaTypeServerWebExchangeMatcher(new MediaType[]{MediaType.TEXT_HTML});
            htmlMatcher.setIgnoredMediaTypes(Collections.singleton(MediaType.ALL));
            ServerHttpSecurity.this.defaultEntryPoints.add(0, new DelegateEntry(htmlMatcher, this.authenticationEntryPoint));
            AuthenticationWebFilter authenticationFilter = new AuthenticationWebFilter(this.authenticationManager);
            authenticationFilter.setRequiresAuthenticationMatcher(this.requiresAuthenticationMatcher);
            authenticationFilter.setAuthenticationFailureHandler(this.authenticationFailureHandler);
            authenticationFilter.setAuthenticationConverter(new ServerFormLoginAuthenticationConverter());
            authenticationFilter.setAuthenticationSuccessHandler(this.authenticationSuccessHandler);
            authenticationFilter.setSecurityContextRepository(this.securityContextRepository);
            http.addFilterAt(authenticationFilter, SecurityWebFiltersOrder.FORM_LOGIN);
        }

        private FormLoginSpec() {
            this.defaultSuccessHandler = new RedirectServerAuthenticationSuccessHandler("/");
            this.authenticationSuccessHandler = this.defaultSuccessHandler;
        }
    }

 

 

*************************

示例

 

*********************

config 层

 

WebSecurityConfig

@Configuration
public class WebSecurityConfig {

    @Bean
    public MapReactiveUserDetailsService initMapReactiveUserDetailsService(){
        UserDetails userDetails= User.builder().username("gtlx")
                .passwordEncoder(initPasswordEncoder()::encode)
                .password("123456")
                .authorities("ROLE_USER")
                .build();

        return new MapReactiveUserDetailsService(userDetails);
    }

    @Bean
    public SecurityWebFilterChain initSecurityWebFilterChain(ServerHttpSecurity http){
        http.formLogin().loginPage("/login").requiresAuthenticationMatcher(ServerWebExchangeMatchers.pathMatchers(HttpMethod.POST,"/login/form"))
                .and().authorizeExchange()
                .pathMatchers("/hello").hasAuthority("ROLE_USER")
                .pathMatchers("/**").permitAll();

        http.csrf().disable();

        return http.build();
    }

    @Bean
    public PasswordEncoder initPasswordEncoder(){
        return new BCryptPasswordEncoder();
    }
}

 

*********************

controller 层

 

HelloController

@RestController
public class HelloController {

    @RequestMapping("/hello")
    public String hello(Principal principal){
        return "hello "+principal.getName();
    }
}

 

LoginController

@Controller
public class LoginController {

    @RequestMapping("/login")
    public String login(){
        return "login";
    }
}

 

 

*********************

前端页面

 

login.html




    
    Title


username:
password:

 

 

*************************

使用测试

 

localhost:8080/hello

                         

认证通过后,输出:hello gtlx

 

 

你可能感兴趣的:(spring,security)