Apache Shiro 那点破事

Apache Shiro 是一个框架,可用于身份验证和授权。本文提供了几个示例用来展示如何在 Java™ 应用程序中使用 Shiro 并给出了如何在一个 Grails web 应用程序中使用它的概述。为了从本文中最大限度地受益,您应该习惯于创建 Java 应用程序并安装了如下的几个组件:

  • Java 1.6 JDK
  • Grails(用来运行这些 web 应用程序示例)

在对系统进行安全保障时,有两个安全性元素非常重要:身份验证和授权。虽然这两个术语代表的是不同的含义,但出于它们在应用程序安全性方面各自的角色考虑,它们有时会被交换使用。身份验证和授权

身份验证 指的是验证用户的身份。在验证用户身份时,需要确认用户的身份的确如他们所声称的那样。在大多数应用程序中,身份验证是通过用户名和密码的组合完成的。只要用户选择了他人很难猜到的密码,那么用户名和密码的组合通常就足以确立身份。但是,还有其他的身份验证方式可用,比如指纹、证书和生成键。

一旦身份验证过程成功地建立起身份,授权 就会接管以便进行访问的限制或允许。 所以,有这样的可能性:用户虽然通过了身份验证可以登录到一个系统,但是未经过授权,不准做任何事情。还有一种可能是用户虽然具有了某种程度的授权,却并未经过身份验证。

在为应用程序规划安全性模型时,必须处理好这两个元素以确保系统具有足够的安全性。身份验证是应用程序常见的问题(特别是在只有用户和密码组合的情况下),所以让框架来处理这项工作是一个很好的做法。合理的框架可提供经过测试和维护的优势,让您可以集中精力处理业务问题,而不是解决其解决方案已经实现的问题。

Apache Shiro 提供了一个可用的安全性框架,各种客户机都可将这个框架应用于它们的应用程序。本文中的这些例子旨在介绍 Shiro 并着重展示对用户进行身份验证的基本任务。

了解 Shiro

Shiro 是一个用 Java 语言实现的框架,通过一个简单易用的 API 提供身份验证和授权。使用 Shiro,您就能够为您的应用程序提供安全性而又无需从头编写所有代码。


Shiro 的 
Session 对象允许无需 HttpSession 即可使用一个用户会话。通过使用一个通用的 Session 对象,即便该代码没有在一个 Web 应用程序中运行,仍可以使用相同的代码。没有对应用服务器或 Web 应用服务器会话管理的依赖,您甚至可以在命令行环境中使用 Shiro。换言之,使用 Shiro 的 API 编写的代码让您可以构建连接到 LDAP 服务器的命令行应用程序并且与 web 应用程序内用来访问 LDAP 服务器的代码相同。由于 Shiro 提供具有诸多不同数据源的身份验证,以及 Enterprise Session Management,所以是实现单点登录(SSO)的理想之选 — 大型企业内的一个理想特性,因为在大型企业内,用户需要在一天内经常登录到并使用不同系统。这些数据源包括 JDBC、LDAP、 Kerberos 和 Microsoft® Active Directory® Directory Services (AD DS)。



shiro-springmvc-mybatis登录认证 权限控制


1:shiro jar

[html]  view plain  copy
 print ?
  1. <dependency>  
  2.             <groupId>org.apache.shirogroupId>  
  3.             <artifactId>shiro-coreartifactId>  
  4.             <version>1.2.3version>  
  5.         dependency>  
  6.         <dependency>  
  7.             <groupId>org.apache.shirogroupId>  
  8.             <artifactId>shiro-springartifactId>  
  9.             <version>1.2.3version>  
  10.         dependency>  
  11.         <dependency>  
  12.             <groupId>org.apache.shirogroupId>  
  13.             <artifactId>shiro-casartifactId>  
  14.             <version>1.2.3version>  
  15.             <exclusions>  
  16.                 <exclusion>  
  17.                     <groupId>commons-logginggroupId>  
  18.                     <artifactId>commons-loggingartifactId>  
  19.                 exclusion>  
  20.             exclusions>  
  21.         dependency>  
  22.         <dependency>  
  23.             <groupId>org.apache.shirogroupId>  
  24.             <artifactId>shiro-webartifactId>  
  25.             <version>1.2.3version>  
  26.         dependency>  
  27.         <dependency>  
  28.             <groupId>org.apache.shirogroupId>  
  29.             <artifactId>shiro-ehcacheartifactId>  
  30.             <version>1.2.3version>  
  31.         dependency>  
  32.         <dependency>  
  33.             <groupId>org.apache.shirogroupId>  
  34.             <artifactId>shiro-quartzartifactId>  
  35.             <version>1.2.3version>  
  36.         dependency>  
  37.       
2:shiro 配置文件:

[html]  view plain  copy
 print ?
  1. xml version="1.0" encoding="UTF-8"?>  
  2. <beans xmlns="http://www.springframework.org/schema/beans" xmlns:aop="http://www.springframework.org/schema/aop"  
  3.     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context"  
  4.     xmlns:tx="http://www.springframework.org/schema/tx"  
  5.     xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-2.5.xsd http://www.springframework.org/schema/data/jpa http://www.springframework.org/schema/data/jpa/spring-jpa-1.0.xsd">  
  6.   
  7.     <description>Shiro Configurationdescription>  
  8.   
  9.       
  10.     <bean id="securityManager" class="org.apache.shiro.web.mgt.DefaultWebSecurityManager">  
  11.         <property name="realm" ref="shiroDbRealm" />  
  12.         <property name="cacheManager" ref="cacheManager" />  
  13.     bean>  
  14.   
  15.       
  16.     <bean id="shiroDbRealm" class="com.cat.shiro.ShiroRealm">  
  17.         <property name="cacheManager" ref="cacheManager" />  
  18.     bean>  
  19.   
  20.       
  21.     <bean id="shiroFilter" class="org.apache.shiro.spring.web.ShiroFilterFactoryBean">  
  22.         <property name="securityManager" ref="securityManager" />  
  23.         <property name="successUrl" value="/govern/pages/member/index" />  
  24.         <property name="loginUrl" value="/govern/pages/login" />  
  25.         <property name="unauthorizedUrl" value="/govern/pages/err" />  
  26.           
  27.                   
  28.                 /login/logincs.do = anon  
  29.                 /login/submitcs.do = anon  
  30.                   
  31.                 /** = authc  
  32.             value>  
  33.         property>  
  34.     bean>  
  35.       
  36.     <bean id="cacheManager" class="org.apache.shiro.cache.MemoryConstrainedCacheManager" />  
  37.   
  38.       
  39.     <bean id="lifecycleBeanPostProcessor" class="org.apache.shiro.spring.LifecycleBeanPostProcessor" />  
  40.   
  41.       
  42.     <bean class="org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator"  
  43.         depends-on="lifecycleBeanPostProcessor">  
  44.         <property name="proxyTargetClass" value="true" />  
  45.     bean>  
  46.     <bean class="org.apache.shiro.spring.security.interceptor.AuthorizationAttributeSourceAdvisor">  
  47.         <property name="securityManager" ref="securityManager" />  
  48.     bean>  
  49. beans>  

3:web.xml 对应配置

[html]  view plain  copy
 print ?
  1. <context-param>  
  2. <param-name>contextConfigLocationparam-name>  
  3. <param-value>  
  4. classpath:conf/shiro.xml  
  5. param-value>  
  6. context-param>  
[html]  view plain  copy
 print ?
  1. <filter>    
  2.         <filter-name>shiroFilterfilter-name>    
  3.         <filter-class>org.springframework.web.filter.DelegatingFilterProxyfilter-class>    
  4.         <init-param>    
  5.             <param-name>targetFilterLifecycleparam-name>    
  6.             <param-value>trueparam-value>    
  7.         init-param>    
  8.     filter>    
  9.     <filter-mapping>    
  10.         <filter-name>shiroFilterfilter-name>    
  11.         <url-pattern>/*url-pattern>    
  12.     filter-mapping>    


4:springmvc.xml

[html]  view plain  copy
 print ?
  1. xml version="1.0" encoding="UTF-8"?>  
  2. <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"  
  3.     xmlns:mvc="http://www.springframework.org/schema/mvc" xmlns:context="http://www.springframework.org/schema/context"  
  4.     xmlns:aop="http://www.springframework.org/schema/aop" xmlns:tx="http://www.springframework.org/schema/tx"  
  5.     xsi:schemaLocation="http://www.springframework.org/schema/beans   
  6.             http://www.springframework.org/schema/beans/spring-beans-3.0.xsd   
  7.             http://www.springframework.org/schema/mvc   
  8.             http://www.springframework.org/schema/mvc/spring-mvc-3.0.xsd   
  9.             http://www.springframework.org/schema/context   
  10.             http://www.springframework.org/schema/context/spring-context-3.0.xsd   
  11.             http://www.springframework.org/schema/aop   
  12.             http://www.springframework.org/schema/aop/spring-aop-3.0.xsd   
  13.             http://www.springframework.org/schema/tx   
  14.             http://www.springframework.org/schema/tx/spring-tx-3.0.xsd ">  
  15.   
  16.       
  17.     <context:component-scan base-package="com.hnust.controller">  
  18.         <context:include-filter type="annotation" expression="org.springframework.stereotype.Controller" />  
  19.     context:component-scan>  
  20.       
  21.     <bean class="org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter" />  
  22.     <bean class="org.springframework.web.servlet.mvc.annotation.DefaultAnnotationHandlerMapping" />  
  23.   
  24.       
  25.       
  26.       
  27.       
  28.       
  29.       
  30.     <bean id="viewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver">  
  31.         <property name="prefix" value="/govern/" />  
  32.         <property name="suffix" value=".jsp" />  
  33.     bean>  
  34.       
  35.     <bean id="messageSource" class="org.springframework.context.support.ReloadableResourceBundleMessageSource">  
  36.         <property name="basenames">  
  37.             <list>  
  38.                   
  39.                 <value>classpath:/messagesvalue>  
  40.             list>  
  41.         property>  
  42.         <property name="useCodeAsDefaultMessage" value="false" />  
  43.         <property name="defaultEncoding" value="UTF-8" />  
  44.         <property name="cacheSeconds" value="60" />  
  45.     bean>  
  46.   
  47.   
  48.       
  49.     <bean id="jacksonMessageConverter" class="org.springframework.http.converter.json.MappingJacksonHttpMessageConverter">  
  50.         <property name="supportedMediaTypes">  
  51.             <list>  
  52.                 <value>text/html;charset=UTF-8value>  
  53.             list>  
  54.         property>  
  55.     bean>  
  56.   
  57.       
  58.     <bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver">  
  59.         <property name="defaultEncoding" value="utf-8" />  
  60.         <property name="maxUploadSize" value="10485760000" />  
  61.         <property name="maxInMemorySize" value="40960" />  
  62.     bean>  
  63.   
  64.       
  65.     <bean class="org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator"  
  66.         depends-on="lifecycleBeanPostProcessor">  
  67.         <property name="proxyTargetClass" value="true" />  
  68.     bean>  
  69.   
  70.       
  71.     <bean class="org.springframework.web.servlet.handler.SimpleMappingExceptionResolver">  
  72.         <property name="exceptionMappings">  
  73.             <props>  
  74.                 <prop key="org.apache.shiro.authz.UnauthorizedException">405prop>  
  75.                 <prop key="java.lang.Throwable">405prop>  
  76.             props>  
  77.         property>  
  78.     bean>   
  79.   
  80. beans>    

5:spring.xml

[html]  view plain  copy
 print ?
  1. xml version="1.0" encoding="UTF-8"?>  
  2. <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"  
  3.     xmlns:mvc="http://www.springframework.org/schema/mvc" xmlns:context="http://www.springframework.org/schema/context"  
  4.     xmlns:aop="http://www.springframework.org/schema/aop" xmlns:tx="http://www.springframework.org/schema/tx"  
  5.     xsi:schemaLocation="http://www.springframework.org/schema/beans   
  6.             http://www.springframework.org/schema/beans/spring-beans-3.0.xsd   
  7.             http://www.springframework.org/schema/mvc   
  8.             http://www.springframework.org/schema/mvc/spring-mvc-3.0.xsd   
  9.             http://www.springframework.org/schema/context   
  10.             http://www.springframework.org/schema/context/spring-context-3.0.xsd   
  11.             http://www.springframework.org/schema/aop   
  12.             http://www.springframework.org/schema/aop/spring-aop-3.0.xsd   
  13.             http://www.springframework.org/schema/tx   
  14.             http://www.springframework.org/schema/tx/spring-tx-3.0.xsd ">  
  15.   
  16.   
  17.       
  18.     <context:property-placeholder location="classpath:conf/jdbc.properties" />  
  19.     <context:annotation-config />  
  20.   
  21.       
  22.        
  23.     <context:component-scan base-package="com.hnust">  
  24.         <context:exclude-filter type="annotation" expression="org.springframework.stereotype.Controller" />  
  25.     context:component-scan>  
  26.   
  27.       
  28.       
  29.     <bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">  
  30.         <property name="driverClassName" value="${driverClassName}" />  
  31.         <property name="url" value="${url}" />  
  32.         <property name="username" value="${username}" />  
  33.         <property name="password" value="${password}" />  
  34.           
  35.     <bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">  
  36.         <property name="dataSource" ref="dataSource" />  
  37.         <property name="configLocation" value="classpath:conf/mybatis-config.xml" />  
  38.         <property name="mapperLocations" value="classpath:mapper/*.xml" />      
  39.     bean>  
  40.   
  41.       
  42.     <bean id="baseDao" class="com.hnust.base.BaseDao">  
  43.         <property name="sqlSessionFactory">  
  44.             <ref bean="sqlSessionFactory" />  
  45.         property>  
  46.     bean>  
  47.       
  48.     <bean id="txManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">  
  49.         <property name="dataSource" ref="dataSource" />  
  50.     bean>  
  51.     <tx:advice id="txAdvice" transaction-manager="txManager">  
  52.         <tx:attributes>  
  53.             <tx:method name="insert*" propagation="REQUIRED" />  
  54.             <tx:method name="update*" propagation="REQUIRED" />  
  55.             <tx:method name="delete*" propagation="REQUIRED" />  
  56.             <tx:method name="find" read-only="true" />  
  57.             <tx:method name="get" read-only="true" />  
  58.             <tx:method name="*" propagation="REQUIRED" />  
  59.         tx:attributes>  
  60.     tx:advice>  
  61.     <aop:config>  
  62.         <aop:pointcut expression="execution(* com.hnust.service.impl.*.*(..))" id="pointCut" />  
  63.         <aop:advisor advice-ref="txAdvice" pointcut-ref="pointCut" />  
  64.     aop:config>  
  65.       
  66. beans>  


6:上面说的是配置文件下面贴一下 java代码:

当前贴出来的类对应 上面2 配置文件

pojo类就不贴了 我这里没连数据  只是模拟的用户登录 和手动添加的权限

[java]  view plain  copy
 print ?
  1. /** 
  2.  *  
  3.  */  
  4. package com.cat.shiro;  
  5.   
  6. import java.util.ArrayList;  
  7. import java.util.List;  
  8.   
  9. import org.apache.shiro.authc.AuthenticationException;  
  10. import org.apache.shiro.authc.AuthenticationInfo;  
  11. import org.apache.shiro.authc.AuthenticationToken;  
  12. import org.apache.shiro.authc.SimpleAuthenticationInfo;  
  13. import org.apache.shiro.authc.UsernamePasswordToken;  
  14. import org.apache.shiro.authz.AuthorizationException;  
  15. import org.apache.shiro.authz.AuthorizationInfo;  
  16. import org.apache.shiro.authz.SimpleAuthorizationInfo;  
  17. import org.apache.shiro.realm.AuthorizingRealm;  
  18. import org.apache.shiro.subject.PrincipalCollection;  
  19.   
  20. import com.cat.spring.entity.Role;  
  21. import com.cat.spring.entity.User;  
  22.   
  23. /** 
  24.  */  
  25. public class ShiroRealm extends AuthorizingRealm {  
  26.     /* 
  27.      * 授权 
  28.      */  
  29.     @Override  
  30.     protected AuthorizationInfo doGetAuthorizationInfo(  
  31.             PrincipalCollection principals) {  
  32.         // 根据用户配置用户与权限  
  33.         if (principals == null) {  
  34.             throw new AuthorizationException(  
  35.                     "PrincipalCollection method argument cannot be null.");  
  36.         }  
  37.         String name = (String) getAvailablePrincipal(principals);  
  38.         List roles = new ArrayList();  
  39.         // 简单默认一个用户与角色,实际项目应User user = userService.getByAccount(name);  
  40.         // 根据用户名查询出用户 判断用户信息的有效性 然获取用户的角色权限 授权  
  41.         User user = new User("shiro""123456");  
  42.         if (user.getName().equals(name)) {  
  43.             // 模拟三个角色  
  44.             for (int x = 0; x < 3; x++) {  
  45.                 roles.add("user" + x);  
  46.             }  
  47.         } else {  
  48.             throw new AuthorizationException();  
  49.         }  
  50.         SimpleAuthorizationInfo info = new SimpleAuthorizationInfo();  
  51.         // 增加角色  
  52.         // 取出所有角色授权  
  53.         info.addRoles(roles);  
  54.         // 取出所有权限授权  
  55.         // info.addStringPermissions(permissions);  
  56.         // 模拟拥有的权限  
  57.         info.addStringPermission("cp:updatecs,updatecs1");  
  58.         return info;  
  59.     }  
  60.   
  61.     /* 
  62.      * 认证登录 
  63.      */  
  64.     @SuppressWarnings("unused")  
  65.     @Override  
  66.     protected AuthenticationInfo doGetAuthenticationInfo(  
  67.             AuthenticationToken authcToken) throws AuthenticationException {  
  68.         UsernamePasswordToken token = (UsernamePasswordToken) authcToken;  
  69.         // 简单默认一个用户,实际项目应User user =  
  70.         // userService.getByAccount(token.getUsername());  
  71.         User user = new User("shiro""123456");  
  72.         if (user == null) {  
  73.             throw new AuthorizationException();  
  74.         }  
  75.         SimpleAuthenticationInfo info = null;  
  76.         if (user.getName().equals(token.getUsername())) {  
  77.             info = new SimpleAuthenticationInfo(user.getName(),  
  78.                     user.getPassword(), getName());  
  79.         }  
  80.         return info;  
  81.     }  
  82. }  

7:logincontroller

[java]  view plain  copy
 print ?
  1. package com.hnust.controller;  
  2. @Controller  
  3. @RequestMapping(value = "/login")  
  4. public class LoginController {  
  5.   
  6.   
  7.     /*****************测试shiro************************************/  
  8.       
  9.     @RequestMapping(value = "/logincs", method = RequestMethod.GET)  
  10.     public String logincs() {  
  11.         return "/pages/login";  
  12.     }  
  13.   
  14.     @RequestMapping(value = "/submitcs", method = RequestMethod.POST)  
  15.     public String submitcs(String username, String password) {  
  16.         User user = new User("shiro""123456");  
  17.         try {  
  18.             // 如果登陆成功  
  19.             if (user.getName().equals(username)  
  20.                     && user.getPassword().equals(password)) {  
  21.                 UsernamePasswordToken token = new UsernamePasswordToken(  
  22.                         user.getName(), user.getPassword().toString());  
  23.                 Subject subject = SecurityUtils.getSubject();  
  24.                 subject.login(token);  
  25.                 return "/pages/member/index";  
  26.             } else {  
  27.                 return "/pages/login";  
  28.             }  
  29.         } catch (Exception e) {  
  30.             e.printStackTrace();  
  31.             return "/pages/login";  
  32.         }  
  33.   
  34.     }  
  35.       
  36.   
  37. }  

8:测试权限类 对应上面6 类里面设置的权限访问URL

[java]  view plain  copy
 print ?
  1. package com.hnust.controller;  
  2.   
  3. @Controller  
  4. @RequestMapping(value = "/cp")  
  5. public class CompanyController extends BaseController{  
  6.   
  7.       
  8.     /** 
  9.      * updatecs 
  10.      */  
  11.     @RequiresPermissions("cp:updatecs")  
  12.     @RequestMapping(value="/updatecs",method=RequestMethod.GET)  
  13.     public String updatecs(){  
  14.         System.err.println("成功1");  
  15.         return "index";  
  16.     }  
  17.     /** 
  18.      * updatecs 
  19.      */  
  20.     @RequiresPermissions("cp:updatecs1")  
  21.     @RequestMapping(value="/updatecs1",method=RequestMethod.GET)  
  22.     public String updatecs1(){  
  23.         System.err.println("成功2");  
  24.         return "index";  
  25.     }  
  26.       
  27.     /** 
  28.      * updatecs   这个我没用给当前用户添加权限  是会提示无权限的 
  29.      */  
  30.     @RequiresPermissions("cp:updatecs2")  
  31.     @RequestMapping(value="/updatecs2",method=RequestMethod.GET)  
  32.     public String updatecs2(){  
  33. //      System.err.println("失败");  
  34.         return "index";  
  35.     }  
  36.   
  37. }  

9:下面贴出 效果图

登录不做权限验证:



登录成功:


下面开始进行权限认证:

这是我当前角色有的权限 所以去到了我指定的页面


下面进行 没有权限的URL访问:





你可能感兴趣的:(java)