相关类及接口
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
使用测试
localhost:8080/hello
认证通过后,输出:hello gtlx