Shiro (包含权限知足其中一个就经过的用法)

方法/步骤

  1. web.xml添加配置web


    <!-- shiro过滤器 -->spring

     <filter>数据库

      <filter-name>shiroFilter</filter-name>apache

      <filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>缓存

      <init-param>安全

       <param-name>targetFilterLifecycle</param-name>app

       <param-value>true</param-value>ide

      </init-param>ui

     </filter>url

     <filter-mapping>

      <filter-name>shiroFilter</filter-name>

      <url-pattern>/*</url-pattern>

     </filter-mapping>

  2. shiro与spring整合配置


    <!-- 使用shiro安全检查注解 -->

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



     <!-- shiro的生命周期处理器 -->

     <bean id="lifecycleBeanPostProcessor" class="org.apache.shiro.spring.LifecycleBeanPostProcessor" />

     

     <!-- shiro自带的密码匹配器(用来校验密码足够了) -->

      <bean id="credentialsMatcher" class="org.apache.shiro.authc.credential.SimpleCredentialsMatcher"></bean> 

     <!-- security datasource: -->

     <bean id="myRealm" class="cc.eguid.service.shiro.MyRealm">

      <property name="credentialsMatcher" ref="credentialsMatcher"/><!-- 密码匹配器 -->

            <property name="cachingEnabled" value="false"/><!-- 禁止缓存 -->

     </bean>

     <!-- 安全管理器 -->

     <bean id="securityManager" class="org.apache.shiro.web.mgt.DefaultWebSecurityManager">

      <property name="realm" ref="myRealm" />

     </bean>

     <!-- shiro过滤器 -->

     <bean id="shiroFilter" class="org.apache.shiro.spring.web.ShiroFilterFactoryBean">

      <!-- 配置安全管理器 -->

      <property name="securityManager" ref="securityManager" />

      <!-- 身份认证失败跳转的地址 -->

      <property name="loginUrl" value="/login/" />

      <!-- 身份认证成功跳转的地址 -->

      <property name="successUrl" value="/" />

      <!-- 权限认证失败跳转的地址 -->

      <property name="unauthorizedUrl" value="/login/unauthorized" />

      <property name="filterChainDefinitions">

       <!--anon 表示匿名访问,不须要认证以及受权 -->

       <!--authc表示须要认证 没有进行身份认证是不能进行访问的 -->

       <!--authc,roles[admin]表示是admin角色的用户才能访问 -->

       <value>

        /static/** = anon

        /login/** = anon

        /common/** = anon

        /admin/** = authc,roles[admin]

        /* = authc

        /** = authc

       </value>

      </property>

     </bean>

     

  3. realm和自定义密码校验器实现


    public class MyRealm extends AuthorizingRealm{

     Logger log=Logger.getLogger(MyRealm.class);

     

     @Autowired

        private UserService userService;//这是本身实现的用户信息操做类,实现用户信息,用户角色信息、用户权限信息查询功能

     

     @Override

     protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {

      UserInfo user = (UserInfo) principals.getPrimaryPrincipal();

      SimpleAuthorizationInfo info = new SimpleAuthorizationInfo();

      // 查询角色信息

      Collection<String> roles = userService.findRoles(user);

      info.addRoles(roles);

      log.info("shiro获取用户所属角色列表:"+roles);

      // 查询权限信息

      Collection<String> permissions = userService.findPermissions(user.getSystemuserid());

      info.addStringPermissions(permissions);

      log.info("shiro获取用户权限列表:"+permissions);

      return info;

     }

     

     @Override

     protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token)throws AuthenticationException{

      //用户输入的用户名密码

      String loginname=  token.getPrincipal().toString();

      Object password=token.getCredentials();

      log.info("shiro正在处理尝试登陆的用户信息:"+loginname+",密码:"+new String((char[])password));

      //数据库中的用户信息

      UserInfo user =userService.queryUserInfoByLoginName(loginname);

      if(user==null||CommonUtil.isNull(user.getLoginusername(),user.getPassword(),user.getSystemuserid())){

       return null;

      }

      log.info("shiro获取到当前用户尝试登陆的真实数据:"+user.getLoginusername()+",密码:"+user.getPassword());

      //数据库中的正确的帐户信息

      AuthenticationInfo accountInfo =new SimpleAuthenticationInfo(user, user.getPassword(),getName());

        

      //本身获取密码验证器(因为shiro实现的密码校验方法是密码错误会直接抛异常,不采用,因此改为直接手动校验)

      CredentialsMatcher matcher=getCredentialsMatcher();

      if(matcher==null){

       log.error("没有配置密码匹配器");

       return null;

      }

      //校验密码

      if(matcher.doCredentialsMatch(token,accountInfo)){

       return accountInfo;//校验经过,返回帐号信息

      }

      

      return null;

     }

     

     

    }

  4. 自定义密码校验器


    /**

     * 自定义shiro密码匹配(密码是在md5散列值的基础上再次进行md5加盐操做,加盐值不保存在数据库,而是放在配置文件中)

     * @author eguid

     *

     */

    public class MyCredentialsMatcher extends CodecSupport implements CredentialsMatcher {

     private static final Logger log = LoggerFactory.getLogger(MyCredentialsMatcher.class);

     

     protected Object getCredentials(AuthenticationToken token) {

      return token.getCredentials();

     }

     

     protected Object getCredentials(AuthenticationInfo info) {

      return info.getCredentials();

     }

     

     @Autowired

     private CommonConfigs commonConfigs;

     /**

      * 验证密码

      *

      * @param tokenCredentials

      * @param accountCredentials

      * @return

      */

     protected boolean equals(Object tokenCredentials, Object accountCredentials) {

      if (log.isDebugEnabled()) {

       log.debug("Performing credentials equality check for tokenCredentials of type ["

         + tokenCredentials.getClass().getName() + " and accountCredentials of type ["

         + accountCredentials.getClass().getName() + "]");

      }

      if (isByteSource(tokenCredentials) && isByteSource(accountCredentials)) {

       if (log.isDebugEnabled()) {

        log.debug("Both credentials arguments can be easily converted to byte arrays.  Performing "

          + "array equals comparison");

       }

       byte[] tokenBytes = toBytes(tokenCredentials);

       byte[] accountBytes = toBytes(accountCredentials);

       return MessageDigest.isEqual(tokenBytes, accountBytes);

      } else {

       return accountCredentials.equals(tokenCredentials);

      }

     }

     

     public boolean doCredentialsMatch(AuthenticationToken token, AuthenticationInfo info) {

      Object tokenCredentials = getCredentials(token);

      Object accountCredentials = getCredentials(info);

      String account=String.valueOf((char[])tokenCredentials);

      if(commonConfigs.getMd5salt()==null){

       if (log.isDebugEnabled()) {

        log.debug("配置文件中的加盐值为空,没法进行密码匹配,请确认配置文件是否在指定位置或配置指定加盐值");

       }

       return false;

      }

      String saltaccount=MD5Util.getMD5(account, commonConfigs.getMd5salt());

      if (log.isDebugEnabled()) {

       log.debug("加盐后的密码:"+saltaccount);

      }

      return equals(accountCredentials, saltaccount.toCharArray());

     }

     

    }

  5. 注解使用及模板标签使用

    一、注解使用
    @RequiresPermissions({"user:update:view"})//检查操做权限
    @RequiresPermissions(value={"user:add","user:view"},logical=Logical.OR)//两个操做权限其中一个知足条件便可经过检查
    @RequiresRoles({"admin"})//检查角色
    @RequiresRoles(value={"debug","admin"},logical=Logical.OR)//两个角色其中一个角色知足条件便可

    @RequiresAuthentication//检查是否经过shiro认证
    @RequiresGuest//不须要验证
    @RequiresUser//检查用户是不是当前系统中的用户

    二、标签使用
    使用标签须要先导入shiro的标签库<%@taglib prefix="shiro" uri="http://shiro.apache.org/tags" %>
    (1)显示用户身份信息
    <shiro: principal/>
    默认调用Subject.getPrincipal()获取

    <shiro:principal property="username"/>
    至关于((User)Subject.getPrincipals()).getUsername()

    (2)已登陆shiro用户显示

     <shiro:user> 
    欢迎[<shiro:principal/>]登陆,<a href="logout">退出</a> 
    <shiro:user>

    (3)匿名用户访问
    <shiro:guest>未通过shiro验证的用户(游客,匿名用户)</shiro:guest> 

    (4)已经在shiro登陆过的(已登陆用户)

     <shiro:authenticated> 
        用户[<shiro:principal/>]已身份验证经过 
    <shiro:authenticated>

    (5)没有在shiro登陆过的


     <shiro:notAuthenticated>
        未身份验证(包括记住我)
    <shiro:notAuthenticated>

    (6)检查角色

     <shiro:hasRole name="admin">
        用户[<shiro:principal/>]拥有角色admin<br/>
    <shiro:hasRole>

    检查任意角色(其中一个知足条件即经过,至关于OR)
     <shiro:hasAnyRoles name="admin,user">
        用户[<shiro:principal/>]拥有角色admin或user<br/>
    <shiro:hasAnyRoles>

    不具备角色(反向判断)
     <shiro:lacksRole name="abc">
        用户[<shiro:principal/>]不具备角色abc<br/>
    <shiro:lacksRole>

    (7)操做权限判断

     <shiro:hasPermission name="user:create"> 
        用户[<shiro:principal/>]拥有权限user:create<br/> 
    <shiro:hasPermission>   

    不具备操做权限(反向判断)


     <shiro:lacksPermission name="org:create"> 
        用户[<shiro:principal/>]没有权限org:create<br/> 
    <iro:lacksPermission> 

    END
相关文章
相关标签/搜索