Spring全家桶-Spring Security之自定义表单,认证,鉴权
Spring Security是一个能够为基于Spring的企业应用系统提供声明式的安全访问控制解决方案的安全框架。它提供了一组可以在Spring应用上下文中配置的Bean,充分利用了Spring IoC(控制反转),DI(依赖注入)和AOP(面向切面编程)功能,为应用系统提供声明式的安全访问控制功能,减少了为企业系统安全控制编写大量重复代码的工作。
文章目录
- Spring全家桶-Spring Security之自定义表单,认证,鉴权
- 前言
- 一、Spring Security之自定义表单2
- 二、自定义登陆地址和登陆结果处理
-
- 1.开始撸代码
- 2. 添加配置文件 application.yml
- 3.添加配置类WebSecurityConfig替换掉默认的配置类
- 三.鉴权
-
- 1.设置权限
- 2.验证
前言
我们可以通过自定义的表单进行登陆页的指定,但是有时候,我们是需要前后端分离的,是返回JSON
数据到前端并进行相应的跳转,还有进行登陆成功和登陆失败的处理,我们该怎么处理呢?
默认情况下,Spring Security
只给我们提供了一个默认的用户,就算通过配置的话,也只能设置一个用户,那我们怎么处理呢?还有角色怎么处理?想通过不同的角色,不同权限进行不同的请求连接过滤又该如何处理呢?Spring Security
为我们提供了默认操作方式,现在就开始吧!????
一、Spring Security之自定义表单2
我们继续完善之前的疑问?我们需要处理登录失败和登陆成功的处理,并且需要返回json进行相应的处理,现在进行完善
二、自定义登陆地址和登陆结果处理
1.开始撸代码
- 创建项目spring-security-authentication,pom.xml如下:
<?xml version="1.0" encoding="UTF-8"?><projectxmlns="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:8080spring:security:user:name: tonypassword:123456roles:#指定相关角色,进行鉴权使用-"admin"
3.添加配置类WebSecurityConfig替换掉默认的配置类
修改登陆配置信息,进行相关的配置:WebSecurityConfig
如下:
@EnableWebSecuritypublicclassWebSecurityConfigextendsWebSecurityConfigurerAdapter{@Overrideprotectedvoidconfigure(HttpSecurity http)throwsException{
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()
方法。
//处理登陆成功的逻辑publicfinalTsuccessHandler(AuthenticationSuccessHandler successHandler){this.successHandler= successHandler;returnthis.getSelf();}//处理登陆失败的逻辑publicfinalTfailureHandler(AuthenticationFailureHandler authenticationFailureHandler){this.failureUrl=null;this.failureHandler= authenticationFailureHandler;returnthis.getSelf();}
successHandler()
方法会携带当前登陆用户名及其角色等信息,failureHandler()
方法会携带一个认证异常信息,通过这个异常可以进行相关的自有逻辑处理。
并且我们可以通过defaultSuccessUrl()
方法和failureUrl()
方法进行处理登陆成功和失败的跳转页面,也可以使用successForwardUrl()
方法和failureForwardUrl()
方法进行forward当相关的页面。
当我们使用successHandler
和failureHandler
处理返回JSON
的时候,不会跳转到defaultSuccessUrl和failureUrl指定的url中。
运行程序可以试试:
当登陆成功:
登陆失败:
调试信息:
这里的角色信息,是配置文件里面的。
查询认证信息的时候,通过User类追加的ROLE_
publicUser.UserBuilderroles(String... roles){List<GrantedAuthority> authorities=newArrayList(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(newSimpleGrantedAuthority("ROLE_"+ role));}returnthis.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
实现数据库进行用户管理