Spring全家桶-Spring Security之自定义表单,认证,鉴权
Spring Security是一个能够为基于Spring的企业应用系统提供声明式的安全访问控制解决方案的安全框架。它提供了一组可以在Spring应用上下文中配置的Bean,充分利用了Spring IoC(控制反转),DI(依赖注入)和AOP(面向切面编程)功能,为应用系统提供声明式的安全访问控制功能,减少了为企业系统安全控制编写大量重复代码的工作。
前言
我们可以通过自定义的表单进行登陆页的指定,但是有时候,我们是需要前后端分离的,是返回JSON 数据到前端并进行相应的跳转,还有进行登陆成功和登陆失败的处理,我们该怎么处理呢? 默认情况下,Spring Security 只给我们提供了一个默认的用户,就算通过配置的话,也只能设置一个用户,那我们怎么处理呢?还有角色怎么处理?想通过不同的角色,不同权限进行不同的请求连接过滤又该如何处理呢?Spring Security 为我们提供了默认操作方式,现在就开始吧!😄
一、Spring Security之自定义表单2
我们继续完善之前的疑问?我们需要处理登录失败和登陆成功的处理,并且需要返回json进行相应的处理,现在进行完善
二、自定义登陆地址和登陆结果处理
1.开始撸代码
- 创建项目spring-security-authentication,pom.xml如下:
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<artifactId>spring-security-learn</artifactId>
<groupId>org.tony.spring.security</groupId>
<version>1.0-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>spring-security-authentication</artifactId>
<properties>
<maven.compiler.source>11</maven.compiler.source>
<maven.compiler.target>11</maven.compiler.target>
</properties>
<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>
</project>
2. 添加配置文件 application.yml
server:
port: 8080
spring:
security:
user:
name: tony
password: 123456
roles:
- "admin"
3.添加配置类WebSecurityConfig替换掉默认的配置类
修改登陆配置信息,进行相关的配置:WebSecurityConfig 如下:
@EnableWebSecurity
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
http.authorizeRequests().antMatchers("/book/**")
.hasRole("admin")
.antMatchers("/user/**")
.hasRole("user")
.antMatchers("/index/**")
.permitAll()
.antMatchers("/")
.hasAnyRole("admin","user")
.anyRequest()
.authenticated()
.and()
.formLogin()
.loginPage("/login.html")
.permitAll()
.successHandler((request, response, authentication) -> {
response.setContentType("application/json;charset=UTF-8;");
PrintWriter printWriter = response.getWriter();
String successJson = "{\"code\":\"0000\",\"message\":\"认证成功\",\"success\":true}";
printWriter.write(successJson);
})
.failureHandler((request, response, exception) -> {
response.setContentType("application/json;charset=UTF-8;");
response.setStatus(HttpServletResponse.SC_UNAUTHORIZED);
PrintWriter printWriter = response.getWriter();
String successJson = "{\"code\":\"10001\",\"message\":\"认证失败\",\"success\":false}";
printWriter.write(successJson);
}).and().csrf().disable();
}
}
鉴权问题等会会说到哦。 Spring Security 为我们提供了两个方法,一个是successHandler() 方法,一个是failureHandler() 方法。
public final T successHandler(AuthenticationSuccessHandler successHandler) {
this.successHandler = successHandler;
return this.getSelf();
}
public final T failureHandler(AuthenticationFailureHandler authenticationFailureHandler) {
this.failureUrl = null;
this.failureHandler = authenticationFailureHandler;
return this.getSelf();
}
successHandler() 方法会携带当前登陆用户名及其角色等信息,failureHandler() 方法会携带一个认证异常信息,通过这个异常可以进行相关的自有逻辑处理。 并且我们可以通过defaultSuccessUrl() 方法和failureUrl() 方法进行处理登陆成功和失败的跳转页面,也可以使用successForwardUrl() 方法和failureForwardUrl() 方法进行forward当相关的页面。 当我们使用successHandler 和failureHandler 处理返回JSON 的时候,不会跳转到defaultSuccessUrl和failureUrl指定的url中。 运行程序可以试试: 当登陆成功: 登陆失败: 调试信息: 这里的角色信息,是配置文件里面的。 查询认证信息的时候,通过User类追加的ROLE_
public User.UserBuilder roles(String... roles) {
List<GrantedAuthority> authorities = new ArrayList(roles.length);
String[] var3 = roles;
int var4 = roles.length;
for(int var5 = 0; var5 < var4; ++var5) {
String role = var3[var5];
Assert.isTrue(!role.startsWith("ROLE_"), () -> {
return role + " cannot start with ROLE_ (it is automatically added)";
});
authorities.add(new SimpleGrantedAuthority("ROLE_" + role));
}
return this.authorities((Collection)authorities);
}
在项目中打个断点看看错误信息:
三.鉴权
1.设置权限
我们在上面的配置文件中,设置了/book/** ,/user/** ,/index/** ,并且设置了相应的角色访问权限。
.antMatchers("/book/**")
.hasRole("admin")
.antMatchers("/user/**")
.hasRole("user")
.antMatchers("/index/**")
.permitAll()
.antMatchers("/")
.hasAnyRole("admin","user")
antMatchers() 是一个采用ANT模式的URL匹配器。 ANT模式使用
- ?:匹配任意单个字符,
- *:匹配0或任意数量的字符
- **:匹配0或者更多的目录
上面说明book的路径下需要admin权限,user路径下,需要user权限, index路径下不需要权限,可以公开访问。 我们现在登陆的用户是配置文件中的用户,是通过在内存 中去处理用户的信息,到时候我们会将用户信息保存到数据库 中进行处理。
2.验证
登陆用户为:tony,密码:123456,并且角色为admin 我看看运行情况:当用此用户访问user接口 因为没有权限,因此会配置错误页面,spring的错误页为/error.html 当我们访问book接口试试: 说明当前接口是可以访问的。当我们登出之后,访问index接口试试 同时在访问user接口和book接口全部都要跳转到登陆页 说明这两个接口是需要鉴权的。但是我们现在还是只有一个用户,然而多个用户的情况下,怎么处理了?
- 通过
InMemoryUserDetailsManager 实现内存进行用户管理 - 通过
JdbcUserDetailsManager 实现数据库进行用户管理
|