版权声明:本文为博主原创文章,未经博主允许不得转载。 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、测试结果
启动应用后,可以按前方的测试过程测试,下图分别是登录成功和登录失败的结果: