Spring security 03-自定义登陆成功后的处理逻辑

Spring security 系列博客目录

对应源代码

说在前面

上一篇咱们说到如何在 spring security 中自定义登陆处理逻辑,这一篇咱们来说一下如何自定义登陆成功后的处理逻辑。先来回顾下默认状况下,登陆成功事后spring security 会帮咱们作些什么: 未登陆的状况下,咱们直接访问应用中的资源,页面会自动跳转到登陆页;当登陆成功后,页面会自动重定向到我登陆前请求的 url。html

如何更改默认的登陆成功后的处理结果

好比:若是咱们想在登陆成功后,响应一个 json 字符串(包括“登陆成功”这样的提示信息,响应code,以及跳转的url)给前端。应该怎么办?前端

步骤 1

首先复制上一节的项目工程 spring-security-02,重命名为 Spring-security-03。 maven 依赖不须要改变,以下所示:git

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

	</dependencies>

步骤2

定义登陆成功后的处理类 GoAuthenticationSuccessHandlergithub

/**
	 * 自定义 登陆成功 处理类
	 */
	[@Component](https://my.oschina.net/u/3907912)
	public class GoAuthenticationSuccessHandler implements AuthenticationSuccessHandler {

		@Autowired
		private ObjectMapper objectMapper;

		/**
		 * {"code":200,"message":"操做成功","data":"登陆成功"}
		 * [@param](https://my.oschina.net/u/2303379) request
		 * [@param](https://my.oschina.net/u/2303379) response
		 * [@param](https://my.oschina.net/u/2303379) authentication
		 * @throws IOException
		 * @throws ServletException
		 */
		@Override
		public void onAuthenticationSuccess(HttpServletRequest request, HttpServletResponse response, Authentication authentication)
				throws IOException, ServletException {
			response.setHeader("Content-Type", "application/json;charset=utf-8");
			response.getWriter().print(objectMapper.writeValueAsString(CommonResult.success("登陆成功")));
			response.getWriter().flush();
		}
	}

步骤2

在 WebSecurityConfig 配置类中,注入自定义处理类的依赖 :web

@Autowired
private GoAuthenticationSuccessHandler successHandler;
@Autowired
private GoAuthenticationFailureHandler failureHandler;

步骤3

在 protected void configure(HttpSecurity http) 方法中,追加以下代码:spring

// 这些是原本就有的
	http.formLogin()
	.loginPage("/loginPage.html")// 自定义登陆页
	.loginProcessingUrl("/form/login")// 自定义登陆 action, 名字随便起
	// 如下是新增的
	.successHandler(successHandler)// 自定义登陆成功处理类
	.failureHandler(failureHandler);// 自定义登陆失败处理类

小结

从上面的代码中咱们能够看到,新增了两个配置,在 successHandler 和 failureHandler 方法中分别注入了一个处理类,咱们着重看下 GoAuthenticationSuccessHandler 处理类, 经过重写 AuthenticationSuccessHandler 的方法,响应了一段json给前端。 而failureHandler 是登陆失败时作一些处理,在这里咱们会响应登陆失败的message给前端。这些响应结果咱们均可以自定义。 你能够根据实际需求去选择是否须要自定义这些处理类。json

扩展

回顾一下,以前若是用户没有登陆直接访问咱们的应用资源,会自动跳转到登陆页,若是登陆成功后,去访问没有权限的url,会给咱们一段英文提示,大体意思就是没有权限。这些咱们仍然是能够定制的。好比当咱们没有登陆时,给前端提示“用户未登陆”,当咱们没有权限时,提示前端“用户没有权限”。app

步骤1

定义两个处理类 GoAuthenticationEntryPoint 和 GoAccessDeniedHandlermaven

`ide

/**
 * 自定义 未登陆 或者 token 失效 处理类
 */
@Component
public class GoAuthenticationEntryPoint implements AuthenticationEntryPoint {

	@Autowired
	private ObjectMapper objectMapper;

	@Override
	public void commence(HttpServletRequest request, HttpServletResponse response, AuthenticationException authException) throws IOException, ServletException {
		response.setCharacterEncoding("UTF-8");
		response.setContentType("application/json");
		response.getWriter().println(objectMapper.writeValueAsString(CommonResult.unauthorized(authException.getMessage())));
		response.getWriter().flush();
	}
}

/**
 * 自定义没有访问权限处理类
 */
@Component
public class GoAccessDeniedHandler implements AccessDeniedHandler {

	@Autowired
	private ObjectMapper objectMapper;

	/**
	 * @param request
	 * @param response
	 * @param e
	 * @throws IOException
	 * @throws ServletException
	 *
	 * @return {"code":403,"message":"没有相关权限","data":"Access is denied"}
	 */
	@Override
	public void handle(HttpServletRequest request, HttpServletResponse response, AccessDeniedException e) throws IOException, ServletException {
		response.setHeader("Content-Type", "application/json;charset=utf-8");
		response.getWriter().print(objectMapper.writeValueAsString(CommonResult.forbidden(e.getMessage())));
		response.getWriter().flush();
	}
}

`

步骤2

将自定义的两个处理类注入到 WebSecurityConfig 类中

` @Autowired private GoAccessDeniedHandler accessDeniedHandler;

@Autowired
private GoAuthenticationEntryPoint entryPoint;

`

步骤3

打开 WebSecurityConfig 配置类,在 configure 方法中追加以下代码:

@Override protected void configure(HttpSecurity http) throws Exception { // 此处省略一部分代码 http.exceptionHandling() .accessDeniedHandler(accessDeniedHandler)// 用户没有访问权限处理器 .authenticationEntryPoint(entryPoint);// 用户没有登陆处理器 }

总结

上面咱们总共定义了四个处理类,分别做用于如下四种状况发生以后:

  1. 当咱们登陆成功后。
  2. 当咱们登陆失败后。
  3. 当咱们没有登陆而去访问资源时。
  4. 当咱们访问没有权限的资源时。

咱们能够根据实际状况选择性去定义这些处理类,根据具体需求去定义处理逻辑。详细代码能够参考 https://github.com/nimo10050/spring-security-sample/tree/master/spring-security-03

相关文章
相关标签/搜索