zoukankan      html  css  js  c++  java
  • SpringSecurity个性化用户认证流程

    ⒈自定义登录页面

     1 package cn.coreqi.security.config;
     2 
     3 import org.springframework.context.annotation.Bean;
     4 import org.springframework.context.annotation.Configuration;
     5 import org.springframework.security.config.annotation.web.builders.HttpSecurity;
     6 import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
     7 import org.springframework.security.crypto.password.NoOpPasswordEncoder;
     8 import org.springframework.security.crypto.password.PasswordEncoder;
     9 
    10 @Configuration
    11 public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
    12     
    13     @Bean
    14     public PasswordEncoder passwordEncoder(){
    15         return NoOpPasswordEncoder.getInstance();
    16     }
    17 
    18     @Override
    19     protected void configure(HttpSecurity http) throws Exception {
    20         //http.httpBasic()    //httpBasic登录 BasicAuthenticationFilter
    21         http.formLogin()    //表单登录 UsernamePasswordAuthenticationFilter
    22                 //.loginPage("/coreqi-signIn.html")  //指定登录页面
    23                 .loginPage("/authentication/require")
    24                 .loginProcessingUrl("/authentication/form") //指定表单提交的地址用于替换UsernamePasswordAuthenticationFilter默认的提交地址
    25                 .and()
    26                 .authorizeRequests()    //对授权请求进行配置
    27                 .antMatchers("/coreqi-signIn.html").permitAll() //指定登录页面不需要身份认证
    28                 .anyRequest().authenticated()  //任何请求都需要身份认证
    29                 .and().csrf().disable();    //禁用CSRF
    30             //FilterSecurityInterceptor 整个SpringSecurity过滤器链的最后一环
    31     }
    32 }
     1 package cn.coreqi.security.controller;
     2 
     3 import cn.coreqi.security.support.SimpleResponse;
     4 import org.slf4j.Logger;
     5 import org.slf4j.LoggerFactory;
     6 import org.springframework.http.HttpStatus;
     7 import org.springframework.security.web.DefaultRedirectStrategy;
     8 import org.springframework.security.web.RedirectStrategy;
     9 import org.springframework.security.web.savedrequest.HttpSessionRequestCache;
    10 import org.springframework.security.web.savedrequest.RequestCache;
    11 import org.springframework.security.web.savedrequest.SavedRequest;
    12 import org.springframework.util.StringUtils;
    13 import org.springframework.web.bind.annotation.GetMapping;
    14 import org.springframework.web.bind.annotation.ResponseStatus;
    15 import org.springframework.web.bind.annotation.RestController;
    16 
    17 import javax.servlet.http.HttpServletRequest;
    18 import javax.servlet.http.HttpServletResponse;
    19 import java.io.IOException;
    20 
    21 @RestController
    22 public class SecurityController {
    23 
    24     private Logger logger = LoggerFactory.getLogger(getClass());
    25 
    26     //拿到引发跳转的请求
    27     private RequestCache requestCache = new HttpSessionRequestCache();  //SpringSecurity执行身份认证跳转之前会将当前的请求缓存到HttpSessionRequestCache中
    28     //我们可以通过HttpSessionRequestCache把之前缓存的请求拿出来。
    29 
    30     private RedirectStrategy redirectStrategy = new DefaultRedirectStrategy();  //Spring用于跳转的工具
    31 
    32     /**
    33      * 当需要身份认证时,跳转到这里
    34      * @param request
    35      * @param response
    36      * @return
    37      */
    38     @GetMapping("/authentication/require")
    39     @ResponseStatus(code = HttpStatus.UNAUTHORIZED) //返回401状态码
    40     public SimpleResponse requireAuthentication(HttpServletRequest request, HttpServletResponse response) throws IOException {
    41         SavedRequest savedRequest = requestCache.getRequest(request,response);  //SavedRequest就是跳转前的请求
    42         if(savedRequest != null){   //如果请求缓存存在的话
    43             String target = savedRequest.getRedirectUrl();  //拿到引发跳转的请求URL
    44             logger.info("引发跳转的请求URL是:" + target);
    45             if(StringUtils.endsWithIgnoreCase(target,".html")){ //引发跳转的请求URL是否以html结尾
    46                 redirectStrategy.sendRedirect(request,response,"/coreqi-signIn.html"); //将请求跳转到指定的Url
    47             }
    48         }
    49         return new SimpleResponse(401,"访问的服务需要身份认证,请引导用户到登陆页面",null);
    50     }
    51 }

    ⒉自定义登录成功处理

      默认情况下SpringSecurity登录成功了将会跳转到之前引发登录的那个请求上去,如果我们需要自定义登录成功后的处理过程,只需要实现AuthenticationSuccessHandler接口。(SpringSecurity默认的成功处理器是SavedRequestAwareAuthenticationSuccessHandler)

     1 package cn.coreqi.security.authentication;
     2 
     3 import com.fasterxml.jackson.databind.ObjectMapper;
     4 import org.slf4j.Logger;
     5 import org.slf4j.LoggerFactory;
     6 import org.springframework.beans.factory.annotation.Autowired;
     7 import org.springframework.security.core.Authentication;
     8 import org.springframework.security.web.authentication.AuthenticationSuccessHandler;
     9 import org.springframework.stereotype.Component;
    10 
    11 import javax.servlet.ServletException;
    12 import javax.servlet.http.HttpServletRequest;
    13 import javax.servlet.http.HttpServletResponse;
    14 import java.io.IOException;
    15 
    16 @Component("coreqiAuthenticationSuccessHandler")
    17 public class CoreqiAuthenticationSuccessHandler implements AuthenticationSuccessHandler {
    18 
    19     private Logger logger = LoggerFactory.getLogger(getClass());
    20 
    21     @Autowired
    22     private ObjectMapper objectMapper;  //将对象转换为Json的工具类,SpringMVC在启动的时候会自动为我们注册ObjectMapper
    23     /**
    24      *
    25      * @param httpServletRequest    不知道
    26      * @param httpServletResponse   不知道
    27      * @param authentication   Authentication接口是SpringSecurity的一个核心接口,它的作用是封装我们的认证信息,包含认证请求中的一些信息,包括认证请求的ip,Session是什么,以及认证用户的信息等等。
    28      * @throws IOException
    29      * @throws ServletException
    30      */
    31     @Override
    32     public void onAuthenticationSuccess(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Authentication authentication) throws IOException, ServletException {
    33         logger.info("登录成功");
    34 
    35         httpServletResponse.setContentType("application/json;charset=UTF-8");
    36         httpServletResponse.getWriter().write(objectMapper.writeValueAsString(authentication));
    37     }
    38 }

    配置

     1 package cn.coreqi.security.config;
     2 
     3 import org.springframework.beans.factory.annotation.Autowired;
     4 import org.springframework.context.annotation.Bean;
     5 import org.springframework.context.annotation.Configuration;
     6 import org.springframework.security.config.annotation.web.builders.HttpSecurity;
     7 import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
     8 import org.springframework.security.crypto.password.NoOpPasswordEncoder;
     9 import org.springframework.security.crypto.password.PasswordEncoder;
    10 import org.springframework.security.web.authentication.AuthenticationSuccessHandler;
    11 
    12 @Configuration
    13 public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
    14 
    15     @Autowired
    16     private AuthenticationSuccessHandler coreqiAuthenticationSuccessHandler;
    17 
    18     @Bean
    19     public PasswordEncoder passwordEncoder(){
    20         return NoOpPasswordEncoder.getInstance();
    21     }
    22 
    23     @Override
    24     protected void configure(HttpSecurity http) throws Exception {
    25         //http.httpBasic()    //httpBasic登录 BasicAuthenticationFilter
    26         http.formLogin()    //表单登录 UsernamePasswordAuthenticationFilter
    27                 //.loginPage("/coreqi-signIn.html")  //指定登录页面
    28                 .loginPage("/authentication/require")
    29                 .loginProcessingUrl("/authentication/form") //指定表单提交的地址用于替换UsernamePasswordAuthenticationFilter默认的提交地址
    30                 .successHandler(coreqiAuthenticationSuccessHandler) //登录成功以后要用我们自定义的登录成功处理器,不用Spring默认的。
    31                 .and()
    32                 .authorizeRequests()    //对授权请求进行配置
    33                 .antMatchers("/coreqi-signIn.html").permitAll() //指定登录页面不需要身份认证
    34                 .anyRequest().authenticated()  //任何请求都需要身份认证
    35                 .and().csrf().disable();    //禁用CSRF
    36             //FilterSecurityInterceptor 整个SpringSecurity过滤器链的最后一环
    37     }
    38 }

    ⒊自定义登录失败处理

    只需要实现AuthenticationSuccessHandler接口即可。(默认为SimpleUrlAuthenticationFailureHandler)

     1 package cn.coreqi.security.authentication;
     2 
     3 import com.fasterxml.jackson.databind.ObjectMapper;
     4 import org.slf4j.Logger;
     5 import org.slf4j.LoggerFactory;
     6 import org.springframework.beans.factory.annotation.Autowired;
     7 import org.springframework.http.HttpStatus;
     8 import org.springframework.security.core.AuthenticationException;
     9 import org.springframework.security.web.authentication.AuthenticationFailureHandler;
    10 import org.springframework.stereotype.Component;
    11 
    12 import javax.servlet.ServletException;
    13 import javax.servlet.http.HttpServletRequest;
    14 import javax.servlet.http.HttpServletResponse;
    15 import java.io.IOException;
    16 
    17 @Component("coreqiAuthenticationFailureHandler")
    18 public class CoreqiAuthenticationFailureHandler implements AuthenticationFailureHandler {
    19 
    20     private Logger logger = LoggerFactory.getLogger(getClass());
    21 
    22     @Autowired
    23     private ObjectMapper objectMapper;  //将对象转换为Json的工具类,SpringMVC在启动的时候会自动为我们注册ObjectMapper
    24 
    25     /**
    26      *
    27      * @param httpServletRequest    不知道
    28      * @param httpServletResponse   不知道
    29      * @param e AuthenticationException对象包含了在认证过程中发生的错误产生的异常
    30      * @throws IOException
    31      * @throws ServletException
    32      */
    33     @Override
    34     public void onAuthenticationFailure(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, AuthenticationException e) throws IOException, ServletException {
    35         logger.info("登录失败");
    36 
    37 
    38         httpServletResponse.setStatus(HttpStatus.INTERNAL_SERVER_ERROR.value());    //500状态码
    39         httpServletResponse.setContentType("application/json;charset=UTF-8");
    40         httpServletResponse.getWriter().write(objectMapper.writeValueAsString(e));
    41     }
    42 }

    配置

     1 package cn.coreqi.security.config;
     2 
     3 import org.springframework.beans.factory.annotation.Autowired;
     4 import org.springframework.context.annotation.Bean;
     5 import org.springframework.context.annotation.Configuration;
     6 import org.springframework.security.config.annotation.web.builders.HttpSecurity;
     7 import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
     8 import org.springframework.security.crypto.password.NoOpPasswordEncoder;
     9 import org.springframework.security.crypto.password.PasswordEncoder;
    10 import org.springframework.security.web.authentication.AuthenticationFailureHandler;
    11 import org.springframework.security.web.authentication.AuthenticationSuccessHandler;
    12 
    13 @Configuration
    14 public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
    15 
    16     @Autowired
    17     private AuthenticationSuccessHandler coreqiAuthenticationSuccessHandler;
    18 
    19     @Autowired
    20     private AuthenticationFailureHandler coreqiAuthenticationFailureHandler;
    21 
    22     @Bean
    23     public PasswordEncoder passwordEncoder(){
    24         return NoOpPasswordEncoder.getInstance();
    25     }
    26 
    27     @Override
    28     protected void configure(HttpSecurity http) throws Exception {
    29         //http.httpBasic()    //httpBasic登录 BasicAuthenticationFilter
    30         http.formLogin()    //表单登录 UsernamePasswordAuthenticationFilter
    31                 //.loginPage("/coreqi-signIn.html")  //指定登录页面
    32                 .loginPage("/authentication/require")
    33                 .loginProcessingUrl("/authentication/form") //指定表单提交的地址用于替换UsernamePasswordAuthenticationFilter默认的提交地址
    34                 .successHandler(coreqiAuthenticationSuccessHandler) //登录成功以后要用我们自定义的登录成功处理器,不用Spring默认的。
    35                 .failureHandler(coreqiAuthenticationFailureHandler) //自己体会把
    36                 .and()
    37                 .authorizeRequests()    //对授权请求进行配置
    38                 .antMatchers("/coreqi-signIn.html").permitAll() //指定登录页面不需要身份认证
    39                 .anyRequest().authenticated()  //任何请求都需要身份认证
    40                 .and().csrf().disable();    //禁用CSRF
    41             //FilterSecurityInterceptor 整个SpringSecurity过滤器链的最后一环
    42     }
    43 }
  • 相关阅读:
    指针
    Centos6.5 安装Vim7.4
    C++ Prime:指针和const
    C++ Prime:const的引用
    C++ Prime:函数
    C++ Prime:范围for语句
    python的oop概述
    脚本单独调用django模块
    xtrabackup备份之xbstream压缩
    MySQL8.0安装
  • 原文地址:https://www.cnblogs.com/fanqisoft/p/10617527.html
Copyright © 2011-2022 走看看