为什么使用安全框架
我们的一个普通项目,没有安全的限制也是可以使用的,但是在公司里面,安全就是必须的,不是说非要使用安全框架springsecurity框架。之前我们学过的过滤器,拦截器也是可以实现一定的项目的安全。
市面上存在比较有名的:Shiro,Spring Security !
每一个框架的出现都是为了解决某一问题而产生了,那么Spring Security框架的出现是为了解决什么问题呢?
简化项目的安全的开发,拦截器和过滤器是原生的安全,现在升级了,将这些整合了,变为了框架,以后我们就不需要自己配置拦截器了,直接使用框架就可以了。
一般来说,Web 应用的安全性包括用户认证(Authentication)和用户授权(Authorization)两个部分。
框架的讲解
1 搭建项目的环境
创建一个springboot项目,里面写这些依赖
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
<exclusions>
<exclusion>
<groupId>org.junit.vintage</groupId>
<artifactId>junit-vintage-engine</artifactId>
</exclusion>
</exclusions>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
创建简单的页面
以上就是测试环境,启动以后可以看见页面,所以搭建成功,之后就将springsecurity框架加到这个项目里面。怎么加呢?
如何将springsecurity框架加到项目里面使用呢?
认识SpringSecurity
记住几个类:
WebSecurityConfigurerAdapter:自定义Security策略
AuthenticationManagerBuilder:自定义认证策略
@EnableWebSecurity:开启WebSecurity模式
Spring Security的两个主要目标是 “认证” 和 “授权”(访问控制)。
“认证”(Authentication)
身份验证是关于验证您的凭据,如用户名/用户ID和密码,以验证您的身份。
身份验证通常通过用户名和密码完成,有时与身份验证因素结合使用。
“授权” (Authorization)
授权发生在系统成功验证您的身份后,最终会授予您访问资源(如信息,文件,数据库,资金,位置,几乎任何内容)的完全权限。
这个概念是通用的,而不是只在Spring Security 中存在。
项目中使用
1 添加对应的依赖
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
2 写对应的安全的配置
我们要自定义Security策略,所以我们自己写的配置类要继承人家springsecurity给我们的一个类,重写里面的方法,要自定义,当然要继承人家springsecurity的类,并且重写人家类里面的方法。
如果不重写人家类的方法,导入依赖,就会走人家类里面的东西,问题是现在我们要自定义,springsecurity框架走的方法就是一个固定的,既然你自定义,那么就得写同样的方法,所以唯一的办法就是继承人家源码里面的类,重写这个类里面的方法。
WebSecurityConfigurerAdapter
以上的这个类就是springsecurity框架源码里面的类,现在我们自己写的类就要继承这个类,并且重写里面的方法
可以重写这么多的方法,需要根据自己的需求重写,不需要全部重写。
现在我们需要重写的是和配置相关的,所以找和配置相关的方法。现在我们使用这个方法
@EnableWebSecurity // 开启WebSecurity模式
public class SecurityConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
}
}
这个方法里面就可以自己写自己的逻辑了,比如,现在我们想要实现首页是所有的人可以访问,但是功能页只能特定的人访问,这个咋实现,这个方法里面就可以这样写(可以使用链式编程)
重写的方法参数是http这个对象,这个对象里面有很多的方法,看你需要什么,就写什么,现在我们可以使用
@EnableWebSecurity // 开启WebSecurity模式
public class SecurityConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
// 定制请求的授权规则
// 首页所有人可以访问
// authorizeRequests()这个方法的意思是 : 这个认证需求是
// antMatchers() 哪些路径需要定义访问规则
// permitAll() hasRole() 这些方法的意思是 需要的权限
http.authorizeRequests().antMatchers("/").permitAll()
.antMatchers("/level1/**").hasRole("vip1")
.antMatchers("/level2/**").hasRole("vip2")
.antMatchers("/level3/**").hasRole("vip3");
}
}
以上只是导入了springsecurity依赖,写了一个配置类,现在重新启动项目
首页是可以访问的,但是要跳转页面,不允许了
403 权限不允许了。
测试一下:发现除了首页都进不去了!因为我们目前没有登录的角色,因为请求需要登录的角色拥有对应的权限才可以!
没有权限是出现403页面,但是我们想要的是没有权限就自动的跳转到登录的页面,这个springsecurity框架有一个登录页,我们配置一个就可以了,这样没有权限的时候就自动的跳转到登录页了。咋配置了
重新启动项目
以上就是springsecurity框架给我们定义的一个页面,这个不需要我们自己写,这个登录的页面是在springsecurity框架的源码里面的,路径也是在源码里面的,我们从这个就可以走进源码
进去这个方法
源码里面这个方法上面有很多的解释,我们找到这句就可以
以上就是关于重写的一个授权的方法,记住,关于用户的授权,就是重写这个方法
关于认证的重写的方法
可是现在登录页面出来了,用户名和密码写啥,这个就是一个问题。这个需要在数据库里面写对应的,但是我们还可以根据这个方法,不需要数据库,那个就是重写认证的方法
重写configure(AuthenticationManagerBuilder auth)方法
//定义认证规则
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
//在内存中定义,也可以在jdbc中去拿....
auth.inMemoryAuthentication()
.withUser("jing").password("123456").roles("vip2","vip3")
.and()
.withUser("root").password("123456").roles("vip1","vip2","vip3")
.and()
.withUser("guest").password("123456").roles("vip1","vip2");
}
以上重写的方法里面,就是在内存里面定义了用户,密码,角色,这样这样配置了,重新启动项目,在登录页面就可以写用户名和密码了。
可是输入之后,跳转到了500页面
后台输出这个报错
这个就是你的密码没有编码,现在需要编码,就是密码加密。现在springsecurity框架给你一些加密的规则,我们看看有什么
PasswordEncoder()
这个是一个接口,下面有很多的实现类,选择一个实现类的加密的规则就可以了
//定义认证规则
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
//在内存中定义,也可以在jdbc中去拿....
auth.inMemoryAuthentication().passwordEncoder(new BCryptPasswordEncoder())
.withUser("jing").password(new BCryptPasswordEncoder().encode("123456")).roles("vip2","vip3")
.and()
.withUser("root").password(new BCryptPasswordEncoder().encode("123456")).roles("vip1","vip2","vip3")
.and()
.withUser("guest").password(new BCryptPasswordEncoder().encode("123456")).roles("vip1","vip2");
}
}
以上配置了密码,之后重新启动项目,就可以实现登录了