zoukankan      html  css  js  c++  java
  • 小白用shiro(1)

    本文来自网易云社区

    作者:王飞


    首先引入一段关于shiro的介绍:

    开发系统中,少不了权限,目前java里的权限框架有SpringSecurity和Shiro(以前叫做jsecurity),对于SpringSecurity:功能太过强大以至于功能比较分散,使用起来也比较复杂,跟Spring结合的比较好。对于初学Spring Security者来说,曲线还是较大,需要深入学习其源码和框架,配置起来也需要费比较大的力气,扩展性也不是特别强。

    对于新秀Shiro来说,好评还是比较多的,使用起来比较简单,功能也足够强大,扩展性也较好。听说连Spring的官方都不用Spring Security,用的是Shiro,足见Shiro的优秀。网上找到两篇介绍:http://www.infoq.com/cn/articles/apache-shiro http://www.ibm.com/developerworks/cn/opensource/os-cn-shiro/,http://itindex.net/detail/50410-apache-shiro-%E4%BD%BF%E7%94%A8%E6%89%8B%E5%86%8C,官网http://shiro.apache.org/ ,使用和配置起来还是比较简单。


    下面只是简单介绍下我们是如何配置和使用Shiro的。

    pom.xml引入相关jar包

    1             <!-- spring结合 -->
     2             <dependency>
     3                 <groupId>org.apache.shiro</groupId>
     4                 <artifactId>shiro-spring</artifactId>
     5                 <version>1.4.0</version>
     6             </dependency>
     7             <!--缓存包-->
     8             <dependency>
     9                 <groupId>org.apache.shiro</groupId>
    10                 <artifactId>shiro-ehcache</artifactId>
    11                 <version>1.4.0</version>
    12             </dependency>
    13             <!--核心包-->
    14             <dependency>
    15                 <groupId>org.apache.shiro</groupId>
    16                 <artifactId>shiro-core</artifactId>
    17                 <version>1.4.0</version>
    18             </dependency>

     web.xml增加过滤

     1     <!-- shiro 权限控制的过滤器 -->
     2     <filter>
     3         <filter-name>shiroFilter</filter-name>
     4         <filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
     5     </filter>
     6 
     7     <filter-mapping>
     8         <filter-name>shiroFilter</filter-name>
     9         <url-pattern>/*</url-pattern>
    10     </filter-mapping>

     增加一个shiro.xml的配置文件

      1 <?xml version="1.0" encoding="UTF-8"?>
     2 <beans xmlns="http://www.springframework.org/schema/beans" 3     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:jee="http://www.springframework.org/schema/jee" 4     xmlns:tx="http://www.springframework.org/schema/tx" xmlns:context="http://www.springframework.org/schema/context" 5     xmlns:util="http://www.springframework.org/schema/util" 6     xsi:schemaLocation=" 7     http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd 
     8     http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.0.xsd 
     9     http://www.springframework.org/schema/jee http://www.springframework.org/schema/jee/spring-jee-3.0.xsd 
    10     http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd11     http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util.xsd"12     default-lazy-init="false">
    13 
    14     <!-- 缓存管理器 使用memory实现 -->
    15 
    16 
    17     <!--rememberMe 30天 -->
    18     <bean id="rememberMeCookie" class="org.apache.shiro.web.servlet.SimpleCookie">
    19         <constructor-arg value="COOKIE_NAME" />
    20         <property name="httpOnly" value="true" />
    21         <property name="maxAge" value="2592000" />
    22 
    23     </bean>
    24 
    25     <!-- rememberMe管理器 -->
    26     <bean id="rememberMeManager" class="org.apache.shiro.web.mgt.CookieRememberMeManager">
    27         <property name="cipherKey" value="#{T(org.apache.shiro.codec.Base64).decode('4AvVhmFLUs0KTA3Kprsdag==')}" />
    28         <property name="cookie" ref="rememberMeCookie" />
    29     </bean>
    30 
    31     <bean id="securityManager" class="org.apache.shiro.web.mgt.DefaultWebSecurityManager">
    32         <!-- 继承AuthorizingRealm的类-->
    33         <property name="realm" ref="userRealm" />
    34         <property name="rememberMeManager" ref="rememberMeManager" />
    35     </bean>
    36 
    37     <!-- Shiro Filter -->
    38     <bean id="shiroFilter" class="org.apache.shiro.spring.web.ShiroFilterFactoryBean">
    39         <property name="securityManager" ref="securityManager" />
    40         <property name="loginUrl" value="/openid" />
    41         <property name="successUrl" value="/manage" />
    42         <property name="unauthorizedUrl" value="/openid" />
    43         <property name="filterChainDefinitions">
    44             <value>
    45                 /api/**=anon46                 /res/**=anon47                 /src/**=anon48                 /health/**=anon49                 /logout=authc50                 /openid=anon51                 /callback=anon52                 /=authc53                 /**=anon54             </value>
    55         </property>
    56     </bean>
    57 
    58 
    59     <!-- Shiro生命周期处理器 -->
    60     <bean id="lifecycleBeanPostProcessor" class="org.apache.shiro.spring.LifecycleBeanPostProcessor" />
    61 
    62 </beans>

     对bean的扫描配置

    1     <!-- shiro相关的配置文件和路径扫描的配置必须要放在项目的mvc的配置文件(即xxx-servlet.xml)里 -->
    2     <aop:config proxy-target-class="true" />
    3 
    4     <bean class="org.apache.shiro.spring.security.interceptor.AuthorizationAttributeSourceAdvisor">
    5         <property name="securityManager" ref="securityManager" />
    6     </bean>

     UserRealm

      1 @Component
     2 public class UserRealm extends AuthorizingRealm {
     3 
     4     private Logger logger = org.slf4j.LoggerFactory.getLogger(UserRealm.class);
     5 
     6     public final static String CREDENTIALS = "openid";
     7 
     8     @Autowired
     9     private SessionService sessionService;
    10     @Autowired
    11     private PermissionService permissionService;
    12 
    13     // 记录是否已经设置过PemissionResover
    14     private boolean hasSetPemissionResover = false;
    15 
    16     @Override
    17     public PermissionResolver getPermissionResolver() {
    18         if (!hasSetPemissionResover) {
    19             setPermissionResolver(new WildcardExtPermissionResolver());
    20             hasSetPemissionResover = true;
    21         }
    22         return super.getPermissionResolver();
    23     }
    24 
    25     /**
    26      * 获取授权信息
    27      *
    28      * @param principals
    29      * @return
    30      */
    31     @Override
    32     protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
    33         try {
    34             Iterator<String> iter = principals.fromRealm(getName()).iterator();
    35             if (!iter.hasNext()) {
    36                 logger.info("shiro 验证 无权限");
    37                 return null;
    38             }
    39             String email = iter.next();
    40             if (!Strings.isNullOrEmpty(email)) {
    41                 // set session
    42                 SessionObject so = sessionService.getSession(email);
    43                 if (so == null) {
    44                     logger.info("so 缓存为空");
    45                     return null;
    46                 }
    47                 SessionUtils.setSo(so);
    48 
    49                 // set auth
    50                 SimpleAuthorizationInfo info = new SimpleAuthorizationInfo();
    51                 info.addStringPermissions(permissionService.getPermsForUser(so.getRoleId()));
    52                 return info;
    53             }
    54             logger.info("邮箱为空");
    55             return null;
    56         } catch (Exception e) {
    57             logger.error("shiro 权限获取异常:", e);
    58             return null;
    59         }
    60     }
    61 
    62     /**
    63      * 获取身份验证相关信息:
    64      *
    65      * @param authcToken
    66      * @return
    67      * @throws AuthenticationException
    68      */
    69     @Override
    70     protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authcToken) throws AuthenticationException {
    71         try {
    72             UsernamePasswordToken token = (UsernamePasswordToken) authcToken;
    73             String email = token.getUsername();
    74             String password = new String(token.getPassword());
    75             if (!StringUtils.isEmpty(email) && CREDENTIALS.equals(password)) {
    76                 SessionObject so = SessionUtils.getSo();
    77                 sessionService.addOrUpdateSession(so);
    78                 return new SimpleAuthenticationInfo(email, CREDENTIALS, getName());
    79             }
    80             logger.info("登录验证失败,shiro 不添加权限信息");
    81             return null;
    82         } catch (Exception e) {
    83             logger.error("shiro 身份验证异常:", e);
    84             return null;
    85         }
    86     }
    87 
    88 
    89 }

    登录调用

                  UsernamePasswordToken token = new UsernamePasswordToken(
                         "username", "password", true);
     
                 SecurityUtils.getSubject().login(token);

    退出调用

    1 SecurityUtils.getSubject().logout();

    权限注解

    @RequiresPermissions(value = {"ROLE_KEY"})


    网易云免费体验馆,0成本体验20+款云产品! 

    更多网易研发、产品、运营经验分享请访问网易云社区




    相关文章:
    【推荐】 如何看待P2P领域的羊毛党?
    【推荐】 类似gitlab代码提交的热力图怎么做?

  • 相关阅读:
    poj3067 Japan(树状数组)
    Codeforces 482C Game with Strings(dp+概率)
    LeetCode -- 推断链表中是否有环
    螺旋矩阵——正逆序
    POJ 3905 Perfect Election(2-sat)
    设计模式 之 桥接
    Codeforces Round #257 (Div. 2)
    [LeetCode][Java] Minimum Window Substring
    Unity特殊目录和脚本编译顺序
    jQuery插件 -- Cookie插件
  • 原文地址:https://www.cnblogs.com/zyfd/p/9728230.html
Copyright © 2011-2022 走看看