基于 Spring Boot 的 SSM 环境整合十六:整合 spring security 三(自定义登录结果)

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/xz2001/article/details/86361091

这一篇主要研究登录成功、登录失败时如何返回结果。

1、方法一:在 WebSecurityConfigurerAdapter 实现类中定义

首先回顾下前文中SecurityConfig类的部分配置:

	@Override
	protected void configure(HttpSecurity http) throws Exception {
		System.out.println("SecurityConfig.configure > http");
		
		http.csrf().disable()
			.authorizeRequests()
				.antMatchers("/manage/demo/hello").permitAll() // 此页面允许任何人访问,即使未登录
				.antMatchers("/manage/demo/info1").hasAnyRole("ADMIN") // 仅允许 ADMIN 角色的用户访问
				.antMatchers("/manage/demo/info2").hasAnyRole("USER") // 仅允许 USER 角色的用户访问
				.anyRequest().denyAll() // 其他资源禁止访问
				.and()
			.formLogin()
				.loginPage("/manage/demo/login") // 自定义登录页面
				.failureUrl("/manage/demo/error") // 登录错误页面
				.permitAll() // 允许任何用户访问
				.and()
			.logout()
				.logoutUrl("/manage/demo/exit") // 退出登录
				.logoutSuccessUrl("/manage/demo/index") // 退出登录成功返回的页面
				.permitAll() // 也允许任务用户访问
				.and()
			.exceptionHandling();
	}

忽略其他内容,主要看 .formLogin() 后的相关配置,这里定义了如下几个参数:

1.loginPage("/manage/demo/login") :实际的登录页面,由自己编写的 view 实现
2.failureUrl("/manage/demo/error") :登录错误页面,即登录失败时的页面,也是由 view 实现

这里没有配置登录成功页面,如果在浏览器中直接访问 /manage/demo/login,使用正确的用户名和密码登录后会提示没有结果。

这里还可以添加一个参数:.defaultSuccessUrl("/manage/demo/ok"),表示登录成功后页面。当然,这要在 DemoController 中增加一个返回结果“ok”,代码如下:

	@GetMapping("/ok")
	@ResponseBody
	public String ok() {
		// 登录失败页面,登录成功时返回的结果
		return "登录成功";
	}

以上方法比较简单直观,但需要编写相应的控制器和视图。接下来使用第二种方法。

2、继承并注册 Authentication Handler

spring sucurity定义了默认的成功结果和失败结果处理对象,我们可以继承这些类,并加入自己的业务逻辑,以返回最终的结果。

2.1 继承成功处理类 SavedRequestAwareAuthenticationSuccessHandler

package com.whowii.website4.security;

import java.io.IOException;
import java.util.HashMap;
import java.util.Map;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

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 com.fasterxml.jackson.databind.ObjectMapper;

@Component("myAuthenticationSuccessHandler")
public class MyAuthenticationSuccessHandler extends SavedRequestAwareAuthenticationSuccessHandler {

	@Autowired
	private ObjectMapper objectMapper;

	@Override
	public void onAuthenticationSuccess(HttpServletRequest request, HttpServletResponse response, Authentication authentication) throws IOException,
			ServletException {
		Map<String, Object> map = new HashMap<>();
		map.put("success", true);
		map.put("code", 100);
		map.put("message", "登录成功");

		response.setContentType("application/json;charset=UTF-8");
		response.getWriter().write(objectMapper.writeValueAsString(map));

		// 如果是要跳转到某个页面的,可以这么设置
//		new DefaultRedirectStrategy().sendRedirect(request, response, "/manage/demo/success");

	}
}

2.2 继承失败处理类 SimpleUrlAuthenticationFailureHandler

package com.whowii.website4.security;

import java.io.IOException;
import java.util.HashMap;
import java.util.Map;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

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 com.fasterxml.jackson.databind.ObjectMapper;

@Component("myAuthenticationFailHander")
public class MyAuthenticationFailHander extends SimpleUrlAuthenticationFailureHandler {
	@Autowired
	private ObjectMapper objectMapper;

	@Override
	public void onAuthenticationFailure(HttpServletRequest request, HttpServletResponse response, AuthenticationException exception)
			throws IOException, ServletException {
		Map<String, Object> map = new HashMap<>();
		map.put("success", false);
		map.put("code", 200);
		map.put("message", "登录失败");
		
		response.setStatus(HttpStatus.INTERNAL_SERVER_ERROR.value());
		response.setContentType("application/json");
		response.setCharacterEncoding("UTF-8");
		
		response.getWriter().write(objectMapper.writeValueAsString(map));

//		new DefaultRedirectStrategy().sendRedirect(request, response, "/manage/demo/failure");
	}
}

2.3 注册成功和失败处理对象

既然,我们自己编写了登录成功和失败处理结果,那就把SecurityConfig中的配置删除,并把注册这两个对象,完成后的代码如下:

package com.whowii.website4.security;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
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;

@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
	@Autowired
	private MyAuthenticationProvider authProvider;
	@Autowired
	private MyAuthenticationSuccessHandler myAuthenticationSuccessHandler;
	@Autowired
	private MyAuthenticationFailHander myAuthenticationFailHander;

	@Override
	protected void configure(AuthenticationManagerBuilder auth) throws Exception {
		auth.authenticationProvider(authProvider);
	}

	@Override
	protected void configure(HttpSecurity http) throws Exception {
		System.out.println("SecurityConfig.configure > http");
		http.csrf().disable()
			.authorizeRequests()
				.antMatchers("/manage/demo/hello").permitAll() // 此页面允许任何人访问,即使未登录
				.antMatchers("/manage/demo/info1").hasAnyRole("ADMIN") // 仅允许 ADMIN 角色的用户访问
				.antMatchers("/manage/demo/info2").hasAnyRole("USER") // 仅允许 USER 角色的用户访问
				.anyRequest().denyAll() // 其他资源禁止访问
				.and()
			.formLogin()
				.loginPage("/manage/demo/login") // 自定义登录页面
				.successHandler(myAuthenticationSuccessHandler)
				.failureHandler(myAuthenticationFailHander)
				.permitAll() // 允许任何用户访问
				.and()
			.logout()
				.logoutUrl("/manage/demo/exit") // 退出登录
				.logoutSuccessUrl("/manage/demo/index") // 退出登录成功返回的页面
				.permitAll() // 也允许任务用户访问
				.and()
			.exceptionHandling();
	}

}

3、测试结果

启动应用后,可以按前方的测试过程测试,下图分别是登录成功和登录失败的结果:

猜你喜欢

转载自blog.csdn.net/xz2001/article/details/86361091