基于SSM的RBAC权限系统(3)-Shiro基于非注解的基础使用
导包
官方并不推荐导入all的方式,而是根据自己需要进行导包,这里为了方便导入all
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>1.7.25</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.slf4j/slf4j-log4j12 -->
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-log4j12</artifactId>
<version>1.7.25</version>
<scope>test</scope>
</dependency>
<!-- https://mvnrepository.com/artifact/org.apache.shiro/shiro-all -->
<dependency>
<groupId>org.apache.shiro</groupId>
<artifactId>shiro-all</artifactId>
<version>1.3.2</version>
</dependency>
<dependency>
如果需要用缓存还要导入ehcache的包
在web.xml文件中配置
<display-name>Archetype Created Web Application</display-name>
<filter>
<filter-name>shiroFilter</filter-name>
<filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
<init-param>
<param-name>targetFilterLifecycle</param-name>
<param-value>true</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>shiroFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
然后可以自己新建shiro的配置文件,我是直接写在applicationContext.xml中
<!-- 以下为Shiro配置 -->
<bean id="securityManager" class="org.apache.shiro.web.mgt.DefaultWebSecurityManager">
//使用缓存需要
<!--<property name="cacheManager" ref="cacheManager"/>-->
<property name="authenticator" ref="authenticator"></property>
<property name="realm" ref="jdbcRealm"/>
//使用缓存需要
<!--<property name="cacheManager" ref="cacheManager"/>-->
</bean>
<!--<bean id="cacheManager" class="org.apache.shiro.cache.ehcache.EhCacheManager">-->
<!--<property name="cacheManagerConfigFile" value="classpath:ehcache.xml"/>-->
<!--</bean>-->
<bean id="authenticator"
class="org.apache.shiro.authc.pam.ModularRealmAuthenticator">
<property name="authenticationStrategy">
<bean class="org.apache.shiro.authc.pam.AtLeastOneSuccessfulStrategy"></bean>
</property>
</bean>
<!--<bean id="cacheManager" class="org.apache.shiro.cache.ehcache.EhCacheManager">-->
<!--<property name="cacheManagerConfigFile" value="classpath:ehcache.xml"/>-->
<!--</bean>-->
<bean id="jdbcRealm" class="cn.etop.rbac.common.shiro.realms.ShiroRealm">
<property name="credentialsMatcher">
<bean class="org.apache.shiro.authc.credential.HashedCredentialsMatcher">
<property name="hashAlgorithmName" value="MD5"></property>
<property name="hashIterations" value="16"></property>
</bean>
</property>
</bean>
//调用配置中的bean的生猛周期
<bean id="lifecycleBeanPostProcessor" class="org.apache.shiro.spring.LifecycleBeanPostProcessor"/>
//如果使用注解才需要下面两个配置
<bean class="org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator" depends-on="lifecycleBeanPostProcessor"/>
<bean class="org.apache.shiro.spring.security.interceptor.AuthorizationAttributeSourceAdvisor">
<property name="securityManager" ref="securityManager"/>
</bean>
//基础使用需要改
<bean id="shiroFilter" class="org.apache.shiro.spring.web.ShiroFilterFactoryBean">
<property name="securityManager" ref="securityManager"/>
//登录界面
<property name="loginUrl" value="/login"/>
<!--<property name="successUrl" value="user/index"/>-->
//认证失败跳转到什么地方
<property name="unauthorizedUrl" value="/login"/>
//不推荐直接在这里配置,建议采用工厂的方式
<!--<property name="filterChainDefinitionMap" ref="filterChainDefinitionMap">-->
<!--</property>-->
<!--<property name="filters">-->
<!--<map>-->
<!--<entry key="perms">-->
<!--<bean-->
<!--class="cn.etop.rbac.common.shiro.Filter.PermissionAuthorizationFilter" />-->
<!--</entry>-->
<!--</map>-->
<!--</property>-->
<property name="filterChainDefinitions">
<value>
/login=anon
/checkUser=anon
/** = authc
</value>
</property>
</bean>
//使用工厂方式
<!--<bean id="filterChainDefinitionMap"-->
<!--factory-bean="filterChainDefinitionMapBuilder" factory-method="buildFilterChainDefinitionMap"></bean>-->
<!--<bean id="filterChainDefinitionMapBuilder"-->
<!--class="cn.etop.rbac.common.shiro.factory.FilterChainDefinitionMapBuilder"></bean>-->
<!--<!– 以上为Shiro配置 –>-->
再来看看工厂中的代码
public class FilterChainDefinitionMapBuilder implements ApplicationContextAware{
@Autowired
IPermissionService permissionService;
@Autowired
private ApplicationContext ctx;
@Autowired
LinkedHashMap<String, String> map;
public LinkedHashMap<String, String> buildFilterChainDefinitionMap() throws Exception {
//这里从数据库拿权限数据
map.put("/login", "anon");
map.put("/checkUser", "anon");
map.put("/**", "authc");
return map;
}
以及Shiro中的内容
doGetAuthenticationInfo:登录时会调用的方法
doGetAuthorizationInfo:权限认证时会调用的方法,在这里更新当前用户的权限
public class ShiroRealm extends AuthorizingRealm {
@Autowired
IloginService loginServiceImpl;
@Autowired
IUserService userService;
@Autowired
IRoleService roleService;
@Override
protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException {
UsernamePasswordToken upToken = (UsernamePasswordToken) authenticationToken;
String username = upToken.getUsername();
boolean isExist=false;
try {
//检查用户名是否存在
isExist = userService.checkUserNameExit(username);
} catch (Exception e) {
e.printStackTrace();
}
if(isExist){
throw new UnknownAccountException("用户不存在!");
}
//从数据库获取该用户的数据
User temp=null;
try {
temp=loginServiceImpl.getUserByAccount (username);
} catch (Exception e) {
e.printStackTrace();
}
Object principal = username;
Object credentials = temp.getPassword();
String realmName = getName();
//加盐,使用当前的帐号
ByteSource credentialsSalt = ByteSource.Util.bytes(username);
SimpleAuthenticationInfo info = null;
info = new SimpleAuthenticationInfo(principal, credentials, credentialsSalt ,realmName);
return info;
}
@Override
protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {
String principal = (String)principalCollection.getPrimaryPrincipal();
User user=null;
try {
//查询当前用户是否存在
user=loginServiceImpl.getUserByAccount(principal);
} catch (Exception e) {
e.printStackTrace();
}
Set<String> permission = new HashSet<>();
try {
//得到该用户所有的权限
permission= PermissionUtil.getPermissionWithUser(user,userService,roleService);
} catch (Exception e) {
e.printStackTrace();
}
SimpleAuthorizationInfo info = new SimpleAuthorizationInfo();
for(String p:permission){
info.addStringPermission(p);
}
return info;
}
}
全局错误补抓,这里可以设置你权限不足后跳转的页面
<bean
class="org.springframework.web.servlet.handler.SimpleMappingExceptionResolver">
<property name="exceptionMappings">
<props>
<prop key="org.apache.shiro.authz.UnauthorizedException">
notpermission
</prop>
<prop key="org.apache.shiro.authz.UnauthenticatedException">
notpermission
</prop>
</props>
</property>
</bean>
完整项目地址
这是我第一个写的web项目,代码烂得飞起,仅供纪念,不做参考
带Shiro版:https://github.com/EnTaroAdunZ/ssm_rbac_shiro.git
不带Shiro版:https://github.com/EnTaroAdunZ/ssm_rbac.git