springboot整合spring-security实现简单的登录注销

参考地址:https://www.jianshu.com/p/18875c2995f1

1、引入maven依赖

<dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-security</artifactId>
        </dependency>

2、Security 配置类 说明登录方式、登录页面、哪个url需要认证、注入登录失败/成功过滤器

@Configuration
public class BrowserSecurityConfig extends WebSecurityConfigurerAdapter {

    /**
     * 注入 Security 属性类配置
     */
    @Autowired
    private SecurityProperties securityProperties;

    /**
     * 注入 自定义的  登录成功处理类
     */
    @Autowired
    private MyAuthenticationSuccessHandler mySuccessHandler;
    /**
     * 注入 自定义的  登录失败处理类
     */
    @Autowired
    private MyAuthenticationFailHandler myFailHandler;

    /**
     * 重写PasswordEncoder  接口中的方法,实例化加密策略
     * @return 返回 BCrypt 加密策略
     */
    @Bean
    public PasswordEncoder passwordEncoder(){
        return new BCryptPasswordEncoder();
    }

    @Override
    protected void configure(HttpSecurity http) throws Exception {

        //登录成功的页面地址
        String redirectUrl = securityProperties.getLoginPage();
        //basic 登录方式
//      http.httpBasic()

        //表单登录 方式
        http.formLogin()
                .loginPage("/authentication/require")
                //登录需要经过的url请求
                .loginProcessingUrl("/authentication/form")
                .successHandler(mySuccessHandler)
                .failureHandler(myFailHandler)
                .and()
                //请求授权
                .authorizeRequests()
                //不需要权限认证的url
                .antMatchers("/authentication/*",redirectUrl).permitAll()
                //任何请求
                .anyRequest()
                //需要身份认证
                .authenticated()
                .and()
                //关闭跨站请求防护
                .csrf().disable();
        //默认注销地址:/logout
        http.logout().
                //注销之后 跳转的页面
                logoutSuccessUrl("/authentication/require");
    }

3、自定义登录成功和失败的处理器

(1)、登录成功

@Component
@Slf4j
public class MyAuthenticationSuccessHandler extends SavedRequestAwareAuthenticationSuccessHandler {
    @Override
    public void onAuthenticationSuccess(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Authentication authentication) throws IOException, ServletException {
         logger.info("登录成功");
          //将 authention 信息打包成json格式返回
            httpServletResponse.setContentType("application/json;charset=UTF-8");
            httpServletResponse.getWriter().write("登录成功");
 } }

(2)、登录失败

@Component
@Slf4j
public class MyAuthenticationFailHandler extends SimpleUrlAuthenticationFailureHandler {
    @Override
    public void onAuthenticationFailure(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, AuthenticationException e) throws IOException, ServletException {
        logger.info("登录失败");
           //设置状态码
            httpServletResponse.setStatus(500);
            //将 登录失败 信息打包成json格式返回
            httpServletResponse.setContentType("application/json;charset=UTF-8");
            httpServletResponse.getWriter().write("登录失败:"+e.getMessage());
 } }

4、UserDetail 类 加载用户数据 , 返回UserDetail 实例 (里面包含用户信息)

@Component
@Slf4j
public class MyUserDetailsService implements UserDetailsService {

    @Autowired
    private PasswordEncoder passwordEncoder;

    /**
     * 根据进行登录
     * @param username
     * @return
     * @throws UsernameNotFoundException
     */
    @Override
    public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
        log.info("登录用户名:"+username);
        String password = passwordEncoder.encode("123456");
        //User三个参数   (用户名+密码+权限)
        //根据查找到的用户信息判断用户是否被冻结
        log.info("数据库密码:"+password);
        return new User(username,password, AuthorityUtils.commaSeparatedStringToAuthorityList("admin"));
    }
}

5、登录路径请求类,.loginPage("/authentication/require")

@RestController
@Slf4j
@ResponseStatus(code = HttpStatus.UNAUTHORIZED)
public class BrowerSecurityController {

    /**
     * 把当前的请求缓存到 session 里去
     */
    private RequestCache requestCache = new HttpSessionRequestCache();

    /**
     * 重定向 策略
     */
    private RedirectStrategy redirectStrategy = new DefaultRedirectStrategy();

    /**
     * 注入 Security 属性类配置
     */
    @Autowired
    private SecurityProperties securityProperties;

    /**
     * 当需要身份认证时 跳转到这里
     */
    @RequestMapping("/authentication/require")
    public SimpleResponse requireAuthentication(HttpServletRequest request, HttpServletResponse response) throws IOException {
        //拿到请求对象
        SavedRequest savedRequest = requestCache.getRequest(request, response);
        if (savedRequest != null){
            //获取 跳转url
            String targetUrl = savedRequest.getRedirectUrl();
            log.info("引发跳转的请求是:"+targetUrl);

            //判断 targetUrl 是不是 .html 结尾, 如果是:跳转到登录页(返回view)
            if (StringUtils.endsWithIgnoreCase(targetUrl,".html")){
                String redirectUrl = securityProperties.getLoginPage();
                redirectStrategy.sendRedirect(request,response,redirectUrl);
            }
        }
        //如果不是,返回一个json 字符串
        return new SimpleResponse("访问的服务需要身份认证,请引导用户到登录页");
    }

6、postman请求测试

(1)未登录请求

(2)、登录

 (3)、再次访问

 (4)、注销

posted @ 2020-01-06 16:38  炫舞风中  阅读(3335)  评论(0编辑  收藏  举报