个性化用户认证流程
- 自定义登录页面
将登录改为可配置
public class BrowserProperties {
private String loginPage = "/fly-login.html";
public String getLoginPage() {
return loginPage;
}
public void setLoginPage(String loginPage) {
this.loginPage = loginPage;
}
}
@ConfigurationProperties(prefix = "fly.properties")
public class SecurityProperties {
private BrowserProperties browser = new BrowserProperties();
public BrowserProperties getBrowser() {
return browser;
}
public void setBrowser(BrowserProperties browser) {
this.browser = browser;
}
}
@Configuration
@EnableConfigurationProperties(SecurityProperties.class)
public class SecurityCoreConfig {
}
如果用户访问的是html就会重定向到登录页面
@RestController
public class BrowserSecutityController{
private RequestCache requestCache = new HttpSessionRequestCache();
private RedirectStrategy redirectStrategy = new DefaultRedirectStrategy();
@Autowired
private SecurityProperties securityProperties;
@GetMapping("authentication/request")
@ResponseStatus(code = HttpStatus.UNAUTHORIZED)
public String requestAuthentication(HttpServletRequest request,HttpServletResponse response) throws IOException {
SavedRequest savedRequest = requestCache.getRequest(request, response);
if (savedRequest!=null){
String targetUrl = savedRequest.getRedirectUrl();
if (StringUtils.endsWithIgnoreCase(targetUrl,".html")){
redirectStrategy.sendRedirect(request,response,securityProperties.getBrowser().getLoginPage());
}
}
return "访问的服务需要身份认证";
}
}
@Configuration
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
@Autowired
private SecurityProperties securityProperties;
// @Autowired
// private PasswordEncoder passwordEncoder;
@Override
protected void configure(HttpSecurity http) throws Exception {
http.formLogin()
.loginPage("/authentication/request")
.loginProcessingUrl("/authentication/form")
.and()
.authorizeRequests()
.antMatchers("/authentication/request",securityProperties.getBrowser().getLoginPage())
.permitAll()
.anyRequest().authenticated()
.and().csrf().disable();
}
}
其他模块使用只需配置 fly.properties.browser.loginPage 就可使用自己的登录页
-
自定义成功与错误处理
也分为json与重定向到页面两种
public enum LoginResponseType { JSON, REDIRECT }
@Component("flyAuthenticationFailureHandler")
public class FlyAuthenticationFailureHandler extends SimpleUrlAuthenticationFailureHandler {
@Autowired
private ObjectMapper objectMapper;
@Autowired
private SecurityProperties securityProperties;
@Override
public void onAuthenticationFailure(HttpServletRequest request, HttpServletResponse response, AuthenticationException exception) throws IOException, ServletException {
if (LoginResponseType.JSON.equals(securityProperties.getBrowser().getLoginType())) {
response.setStatus(HttpStatus.INTERNAL_SERVER_ERROR.value());
response.setContentType("application/json;charset=UTF-8");
response.getWriter().write(objectMapper.writeValueAsString(exception.getMessage()));
}else{
super.onAuthenticationFailure(request, response, exception);
}
}
}
@Component("flyAuthenticationSuccessHandler")
public class FlyAuthenticationSuccessHandler extends SimpleUrlAuthenticationSuccessHandler {
@Autowired
private ObjectMapper objectMapper;
@Autowired
private SecurityProperties securityProperties;
@Override
public void onAuthenticationSuccess(HttpServletRequest request, HttpServletResponse response, Authentication authentication) throws IOException, ServletException {
if (LoginResponseType.JSON.equals(securityProperties.getBrowser().getLoginType())){
response.setContentType("application/json;charset=UTF-8");
response.getWriter().write(objectMapper.writeValueAsString(authentication));
}else {
super.onAuthenticationSuccess(request, response, authentication);
}
}
}
public class BrowserProperties {
private String loginPage = "/fly-login.html";
private LoginResponseType loginType = LoginResponseType.JSON;
public String getLoginPage() {
return loginPage;
}
public void setLoginPage(String loginPage) {
this.loginPage = loginPage;
}
public LoginResponseType getLoginType() {
return loginType;
}
public void setLoginType(LoginResponseType loginType) {
this.loginType = loginType;
}
}
@Configuration
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
@Autowired
private AuthenticationSuccessHandler flyAuthenticationSuccessHandler;
@Autowired
private AuthenticationFailureHandler flyAuthenticationFailureHandler;
@Autowired
private SecurityProperties securityProperties;
@Autowired
private PasswordEncoder passwordEncoder;
@Bean
public PasswordEncoder setPasswordEncoder() {
return new BCryptPasswordEncoder();
}
@Override
protected void configure(HttpSecurity http) throws Exception {
http.formLogin()
.loginPage("/authentication/request")
.loginProcessingUrl("/authentication/form")
.successHandler(flyAuthenticationSuccessHandler)
.failureHandler(flyAuthenticationFailureHandler)
.and()
.authorizeRequests()
.antMatchers("/authentication/request",securityProperties.getBrowser().getLoginPage())
.permitAll()
.anyRequest().authenticated()
.and().csrf().disable();
}
@Bean
public UserDetailsService userDetails(){
InMemoryUserDetailsManager manager = new InMemoryUserDetailsManager();
manager.createUser(User.withUsername("user").password(passwordEncoder.encode("123")).roles("USER").build());
return manager;
}
}
fly.properties.browser.loginType=REDIRECT
-
获取登录信息
方式一:
@GetMapping("/userme") public Object getCurrentUser(){ return SecurityContextHolder.getContext().getAuthentication(); }
方式二:
@GetMapping("/userme2") public Object getCurrentUser2(Authentication authentication){ return authentication; }
只获取userdetail:
@GetMapping("/userme3")
public Object getCurrentUser3(@AuthenticationPrincipal UserDetails userDetails){
return userDetails;
}