shiro入门

1.shiro简单介绍

Apache shiro是一个简单易用的J2EE安全框架,它可用作项目中的认证,授权,加密,session管理等操作,先来几个概念的介绍

  Authentication: 认证。即验证是哪个用户登录。

  Authorization:也被称为访问控制,即决定当前登录用户是否有权限去访问受保护的资源。

  Cryptography:通过加密算法保护数据安全。

  Session Management: 当用户使用你的应用是自身携带的数据。

2.springMVC整合shiro的几个简单步骤

  首先在web.xml中配置下shiro的过滤器,让shiro接受处理需要管理请求,一般来说这个项目的请求都配进去

 

  <filter>
  <!-- 一般来说,shiro的过滤器应该放在其他所有过滤器的最前面,表示请求之前先让shiro处理,但是也不绝对 -->
  <!-- 此处的为shiro对应的过滤器名称,应该跟spring的application中的管理
      shiro的org.apache.shiro.spring.web.ShiroFilterFactoryBean的id同名 -->
    <filter-name>shiroFilter</filter-name>
    <filter-class>
            org.springframework.web.filter.DelegatingFilterProxy
        </filter-class>
    <init-param>
      <param-name>targetFilterLifecycle</param-name>
    <!-- 此处缺省值为false,表示生命周期由SpringApplicationContext管理,
        设置成true表示由ServletContainer管理 -->
      <param-value>true</param-value>
    </init-param>
  </filter>
  <filter-mapping>
    <filter-name>shiroFilter</filter-name>
    <!-- /*表示所有请求均需要shiro拦截处理 -->
    <url-pattern>/*</url-pattern>
  </filter-mapping>

 

  下来进行spring的applicationContext.xml的配置

<!--  这里主要是设置自定义的单Realm应用,若有多个Realm,可使用'realms'属性代替 -->   
        <bean id="securityManager" class="org.apache.shiro.web.mgt.DefaultWebSecurityManager">
            <property name="realm" ref="ShiroRealm" />
        </bean>
        
        <!-- 項目自定义的Realm需要继承AuthorizingRealm
            用来自定义shiroReal,即制定shiro验证用户登录的类为自定义的shiroReal
        -->
        <bean id="ShiroRealm" class="com.fh.interceptor.shiro.ShiroRealm" ></bean>
        
        <!-- Shiro主过滤器本身功能十分强大,其强大之处就在于它支持任何基于URL路径表达式的、自定义的过滤器的执行 -->  
        <!-- Web应用中,Shiro可控制的Web请求必须经过Shiro主过滤器的拦截,Shiro对基于Spring的Web应用提供了完美的支持 -->
        <!-- 此处id应该跟web.xml中的过滤器名称同名 -->
        <bean id="shiroFilter" class="org.apache.shiro.spring.web.ShiroFilterFactoryBean">
            <!-- 注入shiro的安全管理员 ,Shiro的核心安全接口,这个属性是必须的 -->
            <property name="securityManager" ref="securityManager" />
            <!-- 注入登录路径
        loginUrl :没有登录的用户请求需要登录的页面时自动跳转到登录页面,不是必须的属性,
        不输入地址的话会自动寻找项目web项目的根目录下的”/login.jsp”页面,默认会自动寻找Web工程根目录下的"/login.jsp"页面 -->
            <property name="loginUrl" value="/" />
            <!-- 注入登录成功的路径
            successUrl :登录成功默认跳转页面,不配置则跳转至”/”。如果登陆前点击的一个需要登录的页面,
            则在登录自动跳转到那个需要登录的页面。不跳转到此。-->
            <property name="successUrl" value="/index.jsp" />
            <!-- 注入权限不足的路径unauthorizedUrl :没有权限默认跳转的页面。 --> 
            <property name="unauthorizedUrl" value="/login_toLogin" />
            <!-- url权限级别的控制 -->
            <!-- anon:匿名过滤,表示不需要任何权限即可访问-->
            <!-- authc:如果继续操作,需要做对应的表单验证否则不能通过-->
            <!-- logout:登录退出过滤器 -->
            <!-- roles:角色过滤器,判断当前用户是否指定角色 -->
            <property name="filterChainDefinitions">
                <value>
                /static/login/**             = anon
                /plugins/keypad/**             = anon
                /static/js/myjs/**             = authc
                /static/js/**                 = anon
                /uploadFiles/uploadImgs/**     = anon
                   /code.do                     = anon
                   /login_login                 = anon
                   /app**/**                     = anon
                   /weixin/**                     = anon
                   /**                            = authc
                </value>
            </property>
        </bean>

  

 

   自定义realm的案例

   此处代码借鉴自:http://www.cnblogs.com/rodge-run/p/6445963.html

 public class BOSRealm extends AuthorizingRealm {
    @Resource
    private IUserDao userDao;

    //权限认证
    @Override
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken paramAuthenticationToken)
            throws AuthenticationException {
        UsernamePasswordToken token = (UsernamePasswordToken) paramAuthenticationToken;
        String username = token.getUsername();

   //调用userdao根据用户名查询用户
        User user = userDao.findByUsername(username);
        if (user != null) {
            //如果查询的用户存在
            //TODO 与数据库中用户名和密码进行比对。比对成功则返回info,比对失败则抛出对应信息的异常AuthenticationException
            SimpleAuthenticationInfo authenticationInfo = new SimpleAuthenticationInfo(user, 
                    user.getPassword(), this.getClass().getName());
            return authenticationInfo;
        } else {

    //如果查询不到用户, 返回空, Shiro会抛出UnknownAccountException异常
            return null;
        }
    }
    
//授予权限
    @Override
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection paramPrincipalCollection) {
        //创建授权信息对象
        SimpleAuthorizationInfo simpleAuthorizationInfo = new SimpleAuthorizationInfo();
        //根据当前用户查询数据库,获取其权限对象
        //获取当前用户,由于shiro的过滤器在struts的过滤器之前执行,因此此时的用户还没有被封装到session中,
        //故获取当前用户在session中娶不到
        /*Subject subject = SecurityUtils.getSubject();
        User loginUser = (User) subject.getPrincipal();*/
        User loginUser = (User) paramPrincipalCollection.getPrimaryPrincipal();
        if (loginUser != null) {
            List<Function> list = null;
            //表示用户存在,调用roledao根据用户查询所有权限
            if ("admin".equals(loginUser.getUsername())) {
                //如果是超级管理员,赋予所有权限
                list = functionDao.findAll();
            } else {
                //根据用户id查询所有权限
                list = functionDao.findFunctionByUserId(loginUser.getId());
            }
            if (list != null && list.size() > 0) {
                for (Function function : list) {

       //为用户授权
                    simpleAuthorizationInfo.addStringPermission(function.getCode());
                }
            }
            return simpleAuthorizationInfo;
        } else {
            return null;
        }
    }
}

 

 另外,shiro还提供了大量的标签,有需要时再实践了

 

posted @ 2017-05-09 16:18  青春不打烊  阅读(161)  评论(0)    收藏  举报