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; @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">
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<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

启用S​​pring WebFlux安全性 在你的应用程序首先使Webflux安全@EnableWebFluxSecurity @SpringBootApplication @EnableWebFluxSecurity public class SecuredRestApplication { 创建一个InMemory UserDetailsS​​ervice 定义一个自定义UserDetailsService bean,在其中添加具有密码和初始角色的User: @Bean public MapReactiveUserDetailsService userDetailsRepository() { UserDetails user = User . withDefaultPasswordEncoder() .username( " user " )
实现接口 AuthenticationFailureHandler 自定义认证成功处理器 @Component public class CustomAuthenticationFailureHandler implements AuthenticationFailureHandler { @Override public void onAuthenticationFailure(HttpServletRequest request, HttpServletResponse respons
在此项目中naocs服务器是通过mysql来进行连接的,nacos不用手动搭建服务器,对于开发者来说,上手很快。 1.2 Nacos安装和启动 nacos 的下载和启动方法请参考Nacos 官网。 在启动nacos2.01的时候,有个坑,默认启动方式是以集群的方式启动,需要修改, 直接使用命令启动 startup.sh -m standalone 1.3 注册中心客户端搭建 Pom依赖导入: <dependency&.
ExceptionTranslationFilter ExceptionTranslationFilter(Security Filter)允许将AccessDeniedException和AuthenticationException转换为HTTP响应。ExceptionTranslationFilter作为Security Filters之一插入到FilterChainProxy中。 首先,ExceptionTranslationFilter调用FilterChain.doFilter(reques
1. 创建一个登录页面,可以使用JSP、Thymeleaf等模板引擎来实现。 2. 在Spring Security配置文件中,配置登录页面的URL和处理登录请求的URL。 3. 在登录页面中,使用表单提交用户输入的用户名和密码。 4. 在Spring Security配置文件中,配置用户认证的方式,可以使用内存认证、数据库认证、LDAP认证等方式。 5. 在用户认证成功后,可以使用Spring Security提供的默认跳转页面,也可以自定义跳转页面。 6. 在用户认证失败后,可以在登录页面中显示错误信息,或者跳转到自定义的错误页面。 以上就是Spring Security自定义登录页面的基本步骤。