spring security是spring全家桶里的权限控制系统,本质上是一堆过滤器组合而成的。

在我的简历项目中权限控制模块就是利用了spring security模块,实行三级权力控制。

因此,springboot中学会怎么样使用权限控制模块是十分便利的。

一、建立项目

为了方便起见,在建立时选中以下几个选项:

springboot security添加header springboot配置security_用户名

springboot security添加header springboot配置security_spring_02

springboot security添加header springboot配置security_springboot_03

springboot security添加header springboot配置security_spring_04

这样就直接集成了模板引擎Thymeleaf,数据库引擎MySQL,安全模块Security。

然后我们采用mybatis访问数据库进行权限控制。

添加依赖

springboot security添加header springboot配置security_用户名_05

这样就完成了数据库配置。

二、建立网页布局

由于thymeleaf自带了视图解析器,所以,只要按如下配置即可。

springboot security添加header springboot配置security_用户名_06

springboot security添加header springboot配置security_用户名_07

 

然后运行一下,测试。

springboot security添加header springboot配置security_springboot_08

进入主页都是不可以的,说明security模块默认是为所有页面加了权限控制,所以我们要重新配置这些。

三、继承适配器类

适配器是WebSecurityConfigurerAdapter类,意思是Web安全配置适配器。

里面有几个方法比较主要


configure(HttpSecurity http) throws Exception


configure(AuthenticationManagerBuilder auth) throws Exception


前者参数是http,即对http的拦截策略,一般采用流式配置。

后者是授权管理构造器,一般情况下需要使用DaoAuthenticationProvider,也就是利用数据库访问来实现对权限的控制。

 

接下来我们看看怎么样配置这个东西。

首先它的大概流程是这样:

(登录时)

根据configure(HttpSecurity http)的配置进行拦截,如果被拦截进入登录页面(可以自定义)------>

自定义的用户名密码就是权限控制保存的那个,需要用用户名查找用户名-密码-权限这个元组(UserDetail接口)---->

然后传给PasswordEncoder的Macher方法进行对比,显然它是rawpassword(传入密码串)和encodePassword(已经在数据库被加密过的密码串)进行对比--->

如果用户不存在则抛出UserNotFoundException,如果密码不对,则对请求拦截,进入密码错误页面,

否则,进入AuthenticationSuccessHandler,也就是认证成功处理器,这里可以进行一些跳转操作,重定向到某些页面---->

之后就完成了操作。

 

五、各个配件

首先是密码器:

springboot security添加header springboot配置security_springboot_09

这里继承了一个BCrypt的密码器,加密时实现了hash算法(我也不知道是哪个,md5还是sha-1)自动进行对比。

然后我们要配置适配器的内容。

springboot security添加header springboot配置security_spring_10

springboot security添加header springboot配置security_spring_11

一般以bean的形式给出provider。

然后是mapper和pojo。

springboot security添加header springboot配置security_权限控制_12

springboot security添加header springboot配置security_spring_13

就可以进行访问了。

值得注意的一点是:

protected void configure(HttpSecurity http) throws Exception {
        http.csrf().disable();
        http.authorizeRequests()
                .antMatchers("/","/login","/register","/add").permitAll()
                .antMatchers("/user").hasAuthority("USER")
                .antMatchers("/admin").hasAuthority("ADMIN")
                .anyRequest().authenticated()
                .and()
                .formLogin().loginPage("/login").successHandler(successHandler).usernameParameter("username").passwordParameter("password")
                .and()
                .logout().permitAll();


    }

这段我们使用的是权限名,也就是访问XXX应该具有(hasAuthority)YYY权限。

而如果是非要用hasRole那就应该在数据库操作时,存入的是ROLE_USER和ROLE_ADMIN。

这一块是个大坑,一般人很容易在这个role和authority上出错(包括我)。