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

<!DOCTYPE html>
<html lang="en" xmlns="http://www.w3.org/1999/xhtml"
      xmlns:th="http://www.thymeleaf.org" xmlns:sec="https://www.thymeleaf.org/thymeleaf-extras-springsecurity4">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<form th:action="@{/login/form}" th:align="center"method="post">
    username:<input type="text" name="username"><br>
    password:<input type="text" name="password"><br>
    <button>提交</button>
</form>
</body>
</html>

 

 

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

使用测试

 

localhost:8080/hello

                         

认证通过后,输出:hello gtlx

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值