springMvc+spring security 注解方式实现权限控制

2022年8月10日13:16:47

一个项目,权限自然是少不了的,在我来公司一段时间后发现公司后台的管理系统既然没有权限模块,所有人都都是超级管理员,更让人嗤之以鼻的是,整个系统也没有任何操作日志记录,这怎么得了,数据是的何等重要,岂是任谁都能操作的,且不说大家都很正常的使用,万一随便谁有个失误,那可是大事情,没有任何的操作记录,除了问题谁负责呢。所以来公司不久忙里偷闲先将权限搞定,接下来就是操作日志了。但是本人刚入行不是很久,对于权限的实现还是很懵逼的状态,没办法,谁让我很有责任心呢(得意的表情),说干就干,那就先找从喝地方入手了。第一步,当然是技术选型了,目前对于权限的实现有很多种方式喝技术,我了解的只有shrio与spring security了,之前有接触过shrio,不知为何,对shrio没啥好感(有时候女生的感觉还真没啥理由哈),那就security了。因为对security真的只是基于听过的层面,这一路走来真的就是磕磕绊绊,幸好最后完整的实现了,虽然遇到很多问题,现在也依然不完美。但能很有效的使用,此处为自己的一次成长鼓个掌。好了,废话不多说,接下来这篇文章简单介绍下与springMvc整合的配置,以及在jsp,js中如何控制按钮权限。

pom.xml添加

与springMvc 整合

在web.xml中加入security的过滤器

初始化WebSecurity,加载WebSecurityConfigurers

WebSecurityConfig上加入注解@EnableWebSecurity,该注解将WebSecurityConfiguration类引入;同时自己也被Configuration所注解,

WebSecurityConfiguration创建了WebSecurity对象,并且通过WebSecurity对象创建了springSecurityFilterChainFilter加注解后再继承自WebSecurityConfigurerAdapter,继承该类后,将会自动添加如表单登录、记住用户名密码等十来个个Filter,这些Filter是在HttpSecurity中定义的;HttpSecurity又是在WebSecurityConfigurerAdapter中创建的使用的

HttpSecurity用于提供一系列的Security默认的Filter,这个过程中一是生成默认的FilterConfigurer对象并添加到其filters属性中存储;二是调用其performBuild方法生成DefaultSecurityFilterChain对象;在WebSecurityConfig中重载了WebSecurityConfigurerAdapterconfigure方法,利用HttpSercurity对象提供的一些filter去实现我们自己的业务。

如图中所示,MySecurityFilter是自己定义的一个过滤器,继承自AbstractSecurityInterceptor。也就是在使用我们我们自定义的过滤器之前使用HttpFilter去过滤我们的登录等不需要使用权限的资源。

该过滤器的主要作用是通过spring的Ioc生成securityMetadataSource,

登陆后,每次访问资源都会被这个拦截器拦截,会执行doFilter这个方法,这个方法调用了invoke方法

Invoke中调用的beforeInvocation这个方法,它首先会调用MyInvocationSecurityMetadataSource类的getAttributes方法获取被拦截url所需的权限,在调用MyAccessDecisionManagerdecide方法判断用户是否够权限。弄完这一切就会执行下一个拦截器。

在这个过滤器中配置了三个处理类。

(1)这个MyInvocationSecurityMetadaSourceService的作用是从数据库中提取权限资源,供Spring security使用,用于权限校验。

在初始化时,取到所有我们定义的Url资源,以及对应的角色。将Url资源与角色对应的数据封装到一个map中,格式为:{url : [ role1 , role2 ,…]} ,一般规定url为key,权限为value(即以ROLE_为前缀的角色),一个资源可以由多个权限来访问。

该类中的loadResourceDefine只是加载所有的资源与权限的对应关系存到map中,避免每次获取权限都访问数据库(提高性能),然后getAttributes根据参数(被拦截url)返回权限集合。

2authenticationManager这个是处理验证用的,作用是为了拿到用户的验证信息,在登录时调用,这个类实际上是AuthenticationProcessingFilter拦截器调用的。

该类可以有许多provider(提供者)提供用户验证信息,这里自己写了一个类myUserDetailService来获取用户信息。

通过MyUserDetailService拿到用户信息后,authenticationManager对比用户的密码(即验证用户),然后这个AuthenticationProcessingFilter拦截器就过滤。

这个类中只有一个方法

而返回的UserDtails对象中返回了登录用户所拥有的角色

3accessDecisionManager这个也称为授权器,通过登录用户的权限信息、资源、获取资源所需的权限来根据不同的授权策略来判断用户是否有权限访问资源。

decide方法里面写的就是授权策略了,没有明说需要权限的(即没有对应的权限的资源,例如某个请求地址并没有加入到授权地址资源中)可以访问,用户具有其中一个或多个以上的权限的可以访问。

JSP中,使用的是security的标签库,结合自定义标签属性实现权限。

AuthorizeTag为自定义标签类,

该类只有一个方法,继承自TagSupport, doStartTag()方法,遇到标签开始时会呼叫的方法,结合返回值控制是否显示被标签标记得按钮。

在js中实现按钮控制权限

 getBackList方法返回的是当前登录用户无权限的授权地址,此处将无权限的授权地址作为返回值的目的是因为对某个地址没有明说需要权限的情况下允许访问。

AppendBtn方法为具体的使用方法,authUrl为该按钮操作的授权地址,控制按钮是否显示。

以上就简单记录下自己在使用过程中的配置,关于security的原理以及执行流程下篇文章自会为大家意义解析,本文为一个小菜鸟的原创,有问题请大家多多交流、指教。感谢阅读,祝步步高升!

  • 作者:Camellia919
  • 原文链接:https://blog.csdn.net/Camellia919/article/details/81945806
    更新时间:2022年8月10日13:16:47 ,共 2727 字。