安全框架Spring Security(四)——修改登录后处理

安全框架Spring Security(四)——修改登录后处理

简介

默认情况下,我们登陆成功会跳转到之前的请求路径去,如何自定义登陆成功后的一些操作呢,比如:现在流行的前后端分离架构中,调用登陆地址后,并不是需要跳转到哪里,而是需要返回登陆成功及用户信息的json数据;如果登陆失败后,我们需要记录系统日志。
登录后处理分为:
1. 登陆成功后处理;
2. 登陆失败后处理;

登陆成功后处理

(1)声明成功处理器

import com.fasterxml.jackson.databind.ObjectMapper;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.Authentication;
import org.springframework.security.web.authentication.SavedRequestAwareAuthenticationSuccessHandler;
import org.springframework.stereotype.Component;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

/**
 * @ClassName: CloudAuthenticationSuccessHandler
 * @Description: 自定义登录成功处理
 * @Author Marvin
 * @Date 2019/5/24 23:52
 */
@Slf4j
@Component
public class CloudAuthenticationSuccessHandler extends SavedRequestAwareAuthenticationSuccessHandler {

    @Autowired
    private ObjectMapper objectMapper;

    @Override
    public void onAuthenticationSuccess(HttpServletRequest request, HttpServletResponse response, Authentication authentication) throws IOException, ServletException {
        log.info("登录成功");
        // 以json的方式
        response.setContentType("application/json;charset=UTF-8");
        // 返回用户相关信息
     	response.getWriter().write(objectMapper.writeValueAsString(authentication));
    }
}

(2)Spring Security配置成功处理器

在CloudSecurityConfig中我们先注入成功处理器,再配置

import com.marvin.demo.spring.cloud.auth.service.CloudUserDetailsService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.crypto.password.PasswordEncoder;

/**
 * @Author Marvin
 * @Description 身份认证配置
 * @Date 17:14 2019-06-04
 * @Param
 * @return
 **/
@Configuration
@EnableWebSecurity
public class CloudSecurityConfig extends WebSecurityConfigurerAdapter {

	@Autowired
    private CloudAuthenticationSuccessHandler successHandler;

    @Autowired
    private CloudUserDetailsService userDetailsService;

    @Autowired
    private PasswordEncoder passwordEncoder;

    /**
     * 需要配置这个支持password模式
     * support password grant type
     * @return
     * @throws Exception
     */
    @Override
    @Bean
    public AuthenticationManager authenticationManagerBean() throws Exception {
        return super.authenticationManagerBean();
    }

    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
        auth.userDetailsService(userDetailsService).passwordEncoder(passwordEncoder);
    }

    @Override
    protected void configure(HttpSecurity http) throws Exception {
       http.formLogin() //使用formLogin的方式登陆
               .successHandler(successHandler)//登录成功处理器
               .and()
               .authorizeRequests()
               .antMatchers("/login.html").permitAll() //配置不需要校验的路径
               .anyRequest().authenticated()  //任何请求都需要身份认证
               .and().csrf().disable();    //禁用CSRF
    }

}

(3)效果

可以看到,登陆成功后,response是登陆用户信息的json数据
在这里插入图片描述

登陆失败后处理

登陆失败与登陆成功的配置非常相似

(1)声明失败处理器

import com.fasterxml.jackson.databind.ObjectMapper;
import com.marvin.demo.spring.cloud.common.utils.R;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.web.authentication.SimpleUrlAuthenticationFailureHandler;
import org.springframework.stereotype.Component;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

/**
 * @ClassName: CloudAuthenticationSuccessHandler
 * @Description: 自定义登录失败处理
 * @Author Marvin
 * @Date 2019/5/24 23:52
 */
@Slf4j
@Component
public class CloudAuthenticationFailureHandler extends SimpleUrlAuthenticationFailureHandler {

    @Autowired
    private ObjectMapper objectMapper;

    @Override
    public void onAuthenticationFailure(HttpServletRequest request, HttpServletResponse response, AuthenticationException e) throws IOException, ServletException {
        	log.info("登录失败");
        	// 响应状态码
            response.setStatus(HttpStatus.INTERNAL_SERVER_ERROR.value());
            // 以json的方式
            response.setContentType("application/json;charset=UTF-8");
            // 返回错误相关信息
            response.getWriter().write(objectMapper.writeValueAsString(R.error(e.getMessage())));
}

(2)Spring Security配置失败处理器

	@Override
    protected void configure(HttpSecurity http) throws Exception {
       http.formLogin() //使用formLogin的方式登陆
               .successHandler(successHandler)//登录成功处理器
               .failureHandler(failureHandler)//登录失败处理器
               .and()
               .authorizeRequests()
               .antMatchers("/login.html").permitAll() //配置不需要校验的路径
               .anyRequest().authenticated()  //任何请求都需要身份认证
               .and().csrf().disable();    //禁用CSRF
    }

总结

Spring Security是Spring的安全框架,只要几行代码就能实现登陆功能,在单体应用中能发挥作用,其原理后续我们再补充,关于Spring Security的基本使用先叙述到这里。接下来,我们看一下更适用与当前微服务开发的基于Oauth2.0的安全框架Spring Cloud Oauth2(也称 Spring Security Oauth2)是如何使用的。想了解的朋友,关注我后续的文章哦!

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值