我们基本已经看完了JdbcDaoImpl的实现类,已经他做了哪些工作,还学到了如何进行配置简单的权限管理,那么这次说一说权限组的概念。
“
有一个很重要的功能就是在用户(User)和权限(GrantedAuthority)之间添加一个隔离层(a level of indirection——找不到更好的译法了),这通过将GrantedAuthority按照逻辑划分成集合即组(group)来实现。用户能够被分配到一个或多个组,而组的成员被赋予了一系列的GrantedAuthority声明。
”
“
正如在图中所描述的那样,中间的隔离层使得我们可以将相同集合的角色分派给很多人,而这只需要指定新用户到存在的组中即可。将这与我们之前的做法对比,在以前的做法是将GrantedAuthority直接分配给单个的用户
这种将权限进行打包处理的方式可能在以下的场景中用到:
1. 要将用户分成不同的组,而组之间有些角色是重叠的;
2. 想要全局地修改一类用户的权限。如,如果你拥有一个“供应商”的分组,而你想要修改他们能否访问应用特定区域的设置;
3. 拥有大量的用户,你不需要用户级别的授权配置。
1. 要将用户分成不同的组,而组之间有些角色是重叠的;
2. 想要全局地修改一类用户的权限。如,如果你拥有一个“供应商”的分组,而你想要修改他们能否访问应用特定区域的设置;
3. 拥有大量的用户,你不需要用户级别的授权配置。
”
我复制了书中的的这些话,对于我们理解分组权限的概念是很重要的,,,,在我看来,觉得是这样的,前期我们在做权限的时候,我们直接给用户分配了权限,那么现在呢,要进行分组给用户分配权限,其实这个分组的概念就是我们平时说的"分配角色"(我是这么理解的哈。)。
在记住一个概念:"这种将用户权限集中到组中的技术通常叫做基于组的访问控制(Group-Based Access Control ,GBAC)"
(项目中,只提供了两种角色(普通用户:Users,管理员:Admibistrators)。)
我们来看一下基本的配置(这次又使用我们自定义的CustomJdbcDaoimpl类):
- <bean id= "jdbcUserServiceCustom" class="com.packtpub.springsecurity.security.CustomJdbcDaoImpl" >
- <property name= "dataSource" ref="dataSource" />
- <property name= "enableGroups" value="true" />
- <property name= "enableAuthorities" value="false" />
- </bean >
新添加了两个属性值,一个是enableGroups,和enableAuthorities,我们可以从表面上看懂它大概的意思,不过我还是有点好奇,所以查了一下API文档:
enableAuthorities:能够通过权限表加载权限(角色),默认是true
enableGroups:能够支持权限分组,默认是false
接下来配置spring security中的一些初始数据:
- <jdbc:embedded-database id ="dataSource" type="HSQL" >
- <jdbc:script location="classpath:security-schema.sql" />
- <jdbc:script location="classpath:test-users-groups-data.sql" />
- </jdbc:embedded-database >
这些sql语句的解释,在spring security文档中,我们都可以查到的(可以查看文章14找到相关查询方式)。
让我们在回到JdbcDaoImpl类中看一看:
其中有3个查询:
看一下源码:
- this.usersByUsernameQuery = "select username,password,enabled from users where username = ?";
- this.authoritiesByUsernameQuery = "select username,authority from authorities where username = ?";
- this.groupAuthoritiesByUsernameQuery = "select g.id, g.group_name, ga.authority from groups g, group_members gm, group_authorities ga where gm.username = ? and g.id = ga.group_id and g.id = gm.group_id";
看一下这三个查询语句,我们会发现,占位符"?"都是username。这些都是通过用户名查询相关的信息,那我们是不是可以推断出,用户名是唯一的呢?、我们先这么想着。
那么整个JdbcDaoImpl只提供了这三个默认的查询方法,咱们能不能修改这些sql语句呢,应该是可以的,因为这三个属性是符合java bean的规范的。那么我们就可以在扩展类里进行覆盖。
- <bean id= "jdbcUserService" class="com.packtpub.springsecurity.security.CustomJdbcDaoImpl" >
- <property name= "dataSource" ref="dataSource" />
- <property name= "enableGroups" value="true" />
- <property name= "enableAuthorities" value="false" />
- <property name="usersByUsernameQuery" >
- <value> SELECT LOGIN, PASSWORD, 1 FROM USER_INFO WHERE LOGIN = ?</ value>
- </property>
- <property name="groupAuthoritiesByUsernameQuery" >
- <value> SELECT G.GROUP_ID, G.GROUP_NAME, P.NAME
- FROM USER_INFO U
- JOIN USER_GROUP UG on U.USER_INFO_ID = UG.USER_INFO_ID
- JOIN GROUP G ON UG.GROUP_ID = G.GROUP_ID
- JOIN GROUP_PERMISSION GP ON G.GROUP_ID = GP.GROUP_ID
- JOIN PERMISSION P ON GP.PERMISSION_ID = P.PERMISSION_ID
- WHERE U.LOGIN = ? </value>
- </property>
- </bean >
直接对于属性注入就可以了。那么这样我们就可以更改他默认的sql语句了。我们再去看一下同样是JdbcDaoImpl子类的JdbcUserDetailsManager,里边更是很多的sql语句,我们都可以通过同样的注入方式去改变sql语句。其实看到这里,我们可以推断出,如果想要一个不属于默认schame的数据表,然后进行操作也不是一件很难的事情,而且,通过介绍的自定义CustomJdbcDaoImpl,我们也可以推断出,我们可以自己去重写一些方法去完成不同的功能。