基于SSM的RBAC权限系统(3)-Shiro基于非注解的基础使用

来源:互联网 发布:网络大电影拍摄时间 编辑:程序博客网 时间:2024/06/04 18:47

基于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>-->    <!--&lt;!&ndash;       以上为Shiro配置        &ndash;&gt;-->

再来看看工厂中的代码

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