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

基于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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值