zoukankan      html  css  js  c++  java
  • shiro环境搭建及基本操作

    一、pom.xml

      1 <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
      2   xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
      3   <modelVersion>4.0.0</modelVersion>
      4   <groupId>com.sh</groupId>
      5   <artifactId>shirotest</artifactId>
      6   <packaging>war</packaging>
      7   <version>0.0.1-SNAPSHOT</version>
      8   <name>shirotest Maven Webapp</name>
      9   <url>http://maven.apache.org</url>
     10 
     11   <dependencies>
     12   
     13   
     14 <!-- https://mvnrepository.com/artifact/org.apache.shiro/shiro-all -->
     15 <dependency>
     16     <groupId>org.apache.shiro</groupId>
     17     <artifactId>shiro-all</artifactId>
     18     <version>1.2.2</version>
     19 </dependency>
     20 <!-- https://mvnrepository.com/artifact/org.apache.commons/commons-lang3 -->
     21 <dependency>
     22     <groupId>org.apache.commons</groupId>
     23     <artifactId>commons-lang3</artifactId>
     24     <version>3.4</version>
     25 </dependency>
     26   
     27   
     28 <dependency>
     29     <groupId>javax.servlet</groupId>
     30     <artifactId>servlet-api</artifactId>
     31     <version>2.5</version>
     32     <scope>provided</scope>
     33 </dependency>
     34     <dependency>
     35       <groupId>junit</groupId>
     36       <artifactId>junit</artifactId>
     37       <version>3.8.1</version>
     38       <scope>test</scope>
     39     </dependency>
     40     <!-- https://mvnrepository.com/artifact/jstl/jstl -->
     41 <dependency>
     42     <groupId>jstl</groupId>
     43     <artifactId>jstl</artifactId>
     44     <version>1.2</version>
     45 </dependency>
     46     <!-- https://mvnrepository.com/artifact/org.springframework/spring-aop -->
     47     <dependency>
     48         <groupId>org.springframework</groupId>
     49         <artifactId>spring-aop</artifactId>
     50         <version>3.2.0.RELEASE</version>
     51     </dependency>
     52     <!-- https://mvnrepository.com/artifact/org.springframework/spring-aspects -->
     53     <dependency>
     54         <groupId>org.springframework</groupId>
     55         <artifactId>spring-aspects</artifactId>
     56         <version>3.2.0.RELEASE</version>
     57     </dependency>
     58     <!-- https://mvnrepository.com/artifact/org.springframework/spring-beans -->
     59     <dependency>
     60         <groupId>org.springframework</groupId>
     61         <artifactId>spring-beans</artifactId>
     62         <version>3.2.0.RELEASE</version>
     63     </dependency>
     64     <!-- https://mvnrepository.com/artifact/org.springframework/spring-context -->
     65     <dependency>
     66         <groupId>org.springframework</groupId>
     67         <artifactId>spring-context</artifactId>
     68         <version>3.2.0.RELEASE</version>
     69     </dependency>
     70     <!-- https://mvnrepository.com/artifact/org.springframework/spring-context-support -->
     71     <dependency>
     72         <groupId>org.springframework</groupId>
     73         <artifactId>spring-context-support</artifactId>
     74         <version>3.2.0.RELEASE</version>
     75     </dependency>
     76     <!-- https://mvnrepository.com/artifact/org.springframework/spring-core -->
     77     <dependency>
     78         <groupId>org.springframework</groupId>
     79         <artifactId>spring-core</artifactId>
     80         <version>3.2.0.RELEASE</version>
     81     </dependency>
     82     <!-- https://mvnrepository.com/artifact/org.springframework/spring-expression -->
     83     <dependency>
     84         <groupId>org.springframework</groupId>
     85         <artifactId>spring-expression</artifactId>
     86         <version>3.2.0.RELEASE</version>
     87     </dependency>
     88     <!-- https://mvnrepository.com/artifact/org.springframework/spring-instrument -->
     89     <dependency>
     90         <groupId>org.springframework</groupId>
     91         <artifactId>spring-instrument</artifactId>
     92         <version>3.2.0.RELEASE</version>
     93     </dependency>
     94     <!-- https://mvnrepository.com/artifact/org.springframework/spring-instrument-tomcat -->
     95     <dependency>
     96         <groupId>org.springframework</groupId>
     97         <artifactId>spring-instrument-tomcat</artifactId>
     98         <version>3.2.0.RELEASE</version>
     99     </dependency>
    100      <!-- https://mvnrepository.com/artifact/org.springframework/spring-jdbc -->
    101     <dependency>
    102         <groupId>org.springframework</groupId>
    103         <artifactId>spring-jdbc</artifactId>
    104         <version>3.2.0.RELEASE</version>
    105     </dependency>
    106      <!-- https://mvnrepository.com/artifact/org.springframework/spring-orm -->
    107     <dependency>
    108         <groupId>org.springframework</groupId>
    109         <artifactId>spring-orm</artifactId>
    110         <version>3.2.0.RELEASE</version>
    111     </dependency>
    112      <!-- https://mvnrepository.com/artifact/org.springframework/spring-oxm -->
    113     <dependency>
    114         <groupId>org.springframework</groupId>
    115         <artifactId>spring-oxm</artifactId>
    116         <version>3.2.0.RELEASE</version>
    117     </dependency>
    118      <!-- https://mvnrepository.com/artifact/org.springframework/spring-struts -->
    119     <dependency>
    120         <groupId>org.springframework</groupId>
    121         <artifactId>spring-struts</artifactId>
    122         <version>3.2.0.RELEASE</version>
    123     </dependency>
    124      <!-- https://mvnrepository.com/artifact/org.springframework/spring-test -->
    125     <dependency>
    126         <groupId>org.springframework</groupId>
    127         <artifactId>spring-test</artifactId>
    128         <version>3.2.0.RELEASE</version>
    129     </dependency>
    130     <!-- https://mvnrepository.com/artifact/org.springframework/spring-tx -->
    131     <dependency>
    132         <groupId>org.springframework</groupId>
    133         <artifactId>spring-tx</artifactId>
    134         <version>3.2.0.RELEASE</version>
    135     </dependency>
    136     <!-- https://mvnrepository.com/artifact/org.springframework/spring-web -->
    137     <dependency>
    138         <groupId>org.springframework</groupId>
    139         <artifactId>spring-web</artifactId>
    140         <version>3.2.0.RELEASE</version>
    141     </dependency>
    142     <!-- https://mvnrepository.com/artifact/org.springframework/spring-webmvc -->
    143     <dependency>
    144         <groupId>org.springframework</groupId>
    145         <artifactId>spring-webmvc</artifactId>
    146         <version>3.2.0.RELEASE</version>
    147     </dependency>
    148     <!-- https://mvnrepository.com/artifact/org.springframework/spring-webmvc-portlet -->
    149     <dependency>
    150         <groupId>org.springframework</groupId>
    151         <artifactId>spring-webmvc-portlet</artifactId>
    152         <version>3.2.0.RELEASE</version>
    153     </dependency>
    154   </dependencies>
    155   <build>
    156     <finalName>shirotest</finalName>
    157   </build>
    158 </project>
    View Code

     二、SpringMvc.xml

     1 <beans xmlns="http://www.springframework.org/schema/beans"
     2  xmlns:context="http://www.springframework.org/schema/context"
     3  xmlns:p="http://www.springframework.org/schema/p"
     4  xmlns:mvc="http://www.springframework.org/schema/mvc"
     5  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
     6  xsi:schemaLocation="http://www.springframework.org/schema/beans
     7       http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
     8       http://www.springframework.org/schema/context
     9       http://www.springframework.org/schema/context/spring-context.xsd
    10       http://www.springframework.org/schema/mvc
    11       http://www.springframework.org/schema/mvc/spring-mvc-3.0.xsd">
    12      <!-- 启动注解驱动的Spring MVC功能,注册请求url和注解POJO类方法的映射-->
    13      <mvc:annotation-driven />
    14      <!-- 启动包扫描功能,以便注册带有@Controller、@Service、@repository、@Component等注解的类成为spring的bean -->
    15      <context:component-scan base-package="com.**.controller" />
    16       <mvc:default-servlet-handler/>  
    17      <!-- 对模型视图名称的解析,在请求时模型视图名称添加前后缀 -->
    18      <!-- <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver" p:prefix="/" p:suffix=".jsp" /> -->
    19      <bean
    20         class="org.springframework.web.servlet.view.InternalResourceViewResolver">
    21         <property name="prefix">
    22             <value>/</value>
    23         </property>
    24         <property name="suffix">
    25             <value>.jsp</value>
    26         </property>
    27     </bean>
    28 
    29     <!-- shiro注解启用,不可配置在shiro.xml中 -->
    30     <bean class="org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator" depends-on="lifecycleBeanPostProcessor"/>
    31     <bean class="org.apache.shiro.spring.security.interceptor.AuthorizationAttributeSourceAdvisor">
    32         <property name="securityManager" ref="securityManager"/>
    33     </bean>
    34     
    35     <!-- shiro注解拦截未授权时跳转页面 -->
    36     <bean  class="org.springframework.web.servlet.handler.SimpleMappingExceptionResolver">  
    37     <property name="exceptionMappings">  
    38         <props>  
    39             <prop key="org.apache.shiro.authz.AuthorizationException">  
    40                 /meishouquan  <!-- //捕获该异常时跳转的路径 -->
    41             </prop>  
    42         
    43         </props>  
    44     </property>  
    45 </bean> 
    46 </beans>
    View Code

    三、web.xml

     1 <?xml version="1.0" encoding="UTF-8"?>
     2 <web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd" id="WebApp_ID" version="3.0">
     3      <session-config>
     4         <session-timeout>120</session-timeout>
     5     </session-config>
     6   <context-param>
     7     <param-name>contextConfigLocation</param-name>
     8     <param-value>/WEB-INF/spring-*.xml</param-value>
     9   </context-param>
    10   <listener>
    11     <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
    12   </listener>
    13   <servlet-mapping>
    14     <servlet-name>default</servlet-name>
    15     <url-pattern>*.jpg</url-pattern>
    16   </servlet-mapping>
    17   <servlet-mapping>
    18     <servlet-name>default</servlet-name>
    19     <url-pattern>*.js</url-pattern>
    20   </servlet-mapping>
    21   <servlet-mapping>
    22     <servlet-name>default</servlet-name>
    23     <url-pattern>*.css</url-pattern>
    24   </servlet-mapping>
    25   <servlet-mapping>
    26     <servlet-name>default</servlet-name>
    27     <url-pattern>*.docx</url-pattern>
    28   </servlet-mapping>
    29   <servlet>
    30     <servlet-name>spring</servlet-name>
    31     <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
    32     <load-on-startup>1</load-on-startup>
    33   </servlet>
    34   <servlet-mapping>
    35     <servlet-name>spring</servlet-name>
    36     <url-pattern>/</url-pattern>
    37   </servlet-mapping>
    38   
    39    <!--
    40     配置Shiro过滤器
    41     这里filter-name必须对应spring-shiro.xml中定义的<bean id="shiroFilter"/>
    42     使用[/*]匹配所有请求,保证所有的可控请求都经过Shiro的过滤
    43     通常会将此filter-mapping放置到最前面(即其他filter-mapping前面),以保证它是过滤器链中第一个起作用的
    44     -->
    45     <filter>
    46         <filter-name>shiroFilter</filter-name>
    47         <filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
    48         <init-param>
    49             <!-- 缺省为false,表示由SpringApplicationContext管理生命周期,置为true则表示由ServletContainer管理 -->
    50             <param-name>targetFilterLifecycle</param-name>
    51             <param-value>true</param-value>
    52         </init-param>
    53     </filter>
    54     <filter-mapping>
    55         <filter-name>shiroFilter</filter-name>
    56         <url-pattern>/*</url-pattern>
    57     </filter-mapping>
    58 </web-app>
    View Code

    四、spring-shiro.xml

     1 <beans xmlns="http://www.springframework.org/schema/beans"
     2  xmlns:context="http://www.springframework.org/schema/context"
     3  xmlns:p="http://www.springframework.org/schema/p"
     4  xmlns:mvc="http://www.springframework.org/schema/mvc"
     5  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
     6  xsi:schemaLocation="http://www.springframework.org/schema/beans
     7       http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
     8       http://www.springframework.org/schema/context
     9       http://www.springframework.org/schema/context/spring-context.xsd
    10       http://www.springframework.org/schema/mvc
    11       http://www.springframework.org/schema/mvc/spring-mvc-3.0.xsd">
    12      
    13      
    14      <bean id="securityManager" class="org.apache.shiro.web.mgt.DefaultWebSecurityManager">
    15         <!-- 指定Shiro验证用户登录的类为自定义的Realm(若有多个Realm,可使用[realms]属性代替) -->
    16         <property name="realm">
    17             <bean class="com.sh.realm.MyRealm"/>
    18         </property>
    19         <!--
    20         Shiro默认会使用Servlet容器的Session,此时修改超时时间的话,可以修改web.xml或者这里自定义的MyRealm
    21         而若想使用Shiro原生Session则可以设置sessionMode属性为native,此时修改超时时间则只能修改MyRealm
    22         -->
    23         <!-- <property name="sessionMode" value="native"/> -->
    24     </bean>
    25 
    26     <!-- Shiro主过滤器本身功能十分强大,其强大之处就在于它支持任何基于URL路径表达式的、自定义的过滤器的执行 -->
    27     <!-- Web应用中,Shiro可控制的Web请求必须经过Shiro主过滤器的拦截,并且Shiro对基于Spring的Web应用提供了完美的支持 -->
    28     <bean id="shiroFilter" class="org.apache.shiro.spring.web.ShiroFilterFactoryBean">
    29         <!-- Shiro的核心安全接口,这个属性是必须的 -->
    30         <property name="securityManager" ref="securityManager"/>
    31         <!-- 要求登录时的链接(可根据项目的URL进行替换),非必须的属性,默认会找Web工程根目录下的[/login.jsp] -->
    32         <property name="loginUrl" value="/login.jsp"/>
    33         <!-- 登录成功后要跳转的连接(本例中此属性用不到,因为登录成功后的处理逻辑已在LoginController中硬编码为main.jsp) -->
    34         <!-- <property name="successUrl" value="/system/main"/> -->
    35         <!-- 用户访问未授权的资源时,跳转页面-->
    36         <property name="unauthorizedUrl" value="/meishouquan.jsp"/>
    37         <!--拦截配置-->
    38         <property name="filterChainDefinitions">
    39             <value>
    40                 /admin/list**     = authc,perms[admin:manage,admin:add] <!-- 必须登陆,并且具有[]里的权限才可访问 -->
    41                <!--  /admin/list**     = authc,roles[admin] --> <!-- 必须登陆,并且具有[]里的角色才可访问 -->
    42                 /user/info-anon** = anon<!-- 无需登录 -->
    43                 /user/info**      = authc<!-- 需要登陆 -->
    44             </value>
    45         </property>
    46     </bean>
    47 
    48     <!-- 保证实现了Shiro内部lifecycle函数的bean执行 -->
    49     <!-- http://shiro.apache.org/static/1.2.1/apidocs/org/apache/shiro/spring/LifecycleBeanPostProcessor.html -->
    50     <bean id="lifecycleBeanPostProcessor" class="org.apache.shiro.spring.LifecycleBeanPostProcessor"/>
    51 
    52     
    53 <!--开启Shiro的注解(比如@RequiresRoles、@RequiresPermissions)  配置以下两个bean即可实现此功能-->
    54     
    55    <!-- 注意:**下面配置只能在spring.xml中配置生效,必须保证在加载第一个xml时加载此配置 -->
    56     
    57 <!--     <bean class="org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator" depends-on="lifecycleBeanPostProcessor"/>
    58     <bean class="org.apache.shiro.spring.security.interceptor.AuthorizationAttributeSourceAdvisor">
    59         <property name="securityManager" ref="securityManager"/>
    60     </bean> -->
    61    
    62 
    63 </beans>
    View Code

    五、添加页面,点击下载  

    六、添加Controller代码

      1 package com.sh.controller;
      2 
      3 import java.io.IOException;
      4 
      5 import javax.servlet.http.HttpServletRequest;
      6 import javax.servlet.http.HttpServletResponse;
      7 import javax.servlet.http.HttpSession;
      8 
      9 import org.apache.commons.lang3.StringUtils;
     10 import org.apache.commons.lang3.builder.ReflectionToStringBuilder;
     11 import org.apache.commons.lang3.builder.ToStringStyle;
     12 import org.apache.shiro.SecurityUtils;
     13 import org.apache.shiro.authc.AuthenticationException;
     14 import org.apache.shiro.authc.ExcessiveAttemptsException;
     15 import org.apache.shiro.authc.IncorrectCredentialsException;
     16 import org.apache.shiro.authc.LockedAccountException;
     17 import org.apache.shiro.authc.UnknownAccountException;
     18 import org.apache.shiro.authc.UsernamePasswordToken;
     19 import org.apache.shiro.authz.annotation.RequiresGuest;
     20 import org.apache.shiro.authz.annotation.RequiresPermissions;
     21 import org.apache.shiro.authz.annotation.RequiresRoles;
     22 import org.apache.shiro.authz.annotation.RequiresUser;
     23 import org.apache.shiro.subject.Subject;
     24 import org.apache.shiro.web.util.WebUtils;
     25 import org.springframework.stereotype.Controller;
     26 import org.springframework.web.bind.annotation.RequestMapping;
     27 import org.springframework.web.bind.annotation.RequestMethod;
     28 import org.springframework.web.servlet.view.InternalResourceViewResolver;
     29 
     30 /**
     31  * SpringMVC-3.2.4整合Shiro-1.2.2
     32  */
     33 @Controller
     34 @RequestMapping("mydemo")
     35 public class ShiroUserController {
     36       @RequestMapping(value="/test", method=RequestMethod.GET)
     37       public void test(String username, String password, HttpServletRequest request,HttpServletResponse response) throws IOException{
     38           //Subject currentUser = SecurityUtils.getSubject();
     39          // System.out.println(currentUser.);
     40           /*System.out.println(currentUser.isPermitted("admin:manage1"));//判断是否有指定权限
     41           System.out.println(currentUser.hasRole("admin1"));//判断是否有指定角色*/
     42           Object principal = SecurityUtils.getSubject().getPrincipal();//获得当前登录用户名
     43           response.getWriter().print(principal);
     44       }
     45     @RequestMapping("/logout")
     46     public String logout(HttpSession session){
     47         String currentUser = (String)session.getAttribute("currentUser");
     48         System.out.println("用户[" + currentUser + "]准备登出");
     49         SecurityUtils.getSubject().logout();
     50         System.out.println("用户[" + currentUser + "]已登出");
     51         return InternalResourceViewResolver.REDIRECT_URL_PREFIX + "/login.jsp";
     52     }
     53 
     54     @RequestMapping(value="/login", method=RequestMethod.POST)
     55     public String login(String username, String password, HttpServletRequest request){
     56         System.out.println("-------------------------------------------------------");
     57         String rand = (String)request.getSession().getAttribute("rand");
     58         String captcha = WebUtils.getCleanParam(request, "captcha");
     59         System.out.println("用户["+username+"]登录时输入的验证码为["+captcha+"],HttpSession中的验证码为["+rand+"]");
     60         if(!StringUtils.equals(rand, captcha)){
     61             request.setAttribute("message_login", "验证码不正确");
     62             return InternalResourceViewResolver.FORWARD_URL_PREFIX + "/";
     63         }
     64         UsernamePasswordToken token = new UsernamePasswordToken(username, password);
     65        // token.setRememberMe(true);
     66         System.out.print("为验证登录用户而封装的Token:");
     67         System.out.println(ReflectionToStringBuilder.toString(token, ToStringStyle.MULTI_LINE_STYLE));
     68         //获取当前的Subject
     69         Subject currentUser = SecurityUtils.getSubject();
     70         try {
     71             //在调用了login方法后,SecurityManager会收到AuthenticationToken,并将其发送给已配置的Realm执行必须的认证检查
     72             //每个Realm都能在必要时对提交的AuthenticationTokens作出反应
     73             //所以这一步在调用login(token)方法时,它会走到MyRealm.doGetAuthenticationInfo()方法中,具体验证方式详见此方法
     74             System.out.println("对用户[" + username + "]进行登录验证...验证开始");
     75             currentUser.login(token);
     76             System.out.println("对用户[" + username + "]进行登录验证...验证通过");
     77         }catch(UnknownAccountException uae){
     78             System.out.println("对用户[" + username + "]进行登录验证...验证未通过,未知账户");
     79             request.setAttribute("message_login", "未知账户");
     80         }catch(IncorrectCredentialsException ice){
     81             System.out.println("对用户[" + username + "]进行登录验证...验证未通过,错误的凭证");
     82             request.setAttribute("message_login", "密码不正确");
     83         }catch(LockedAccountException lae){
     84             System.out.println("对用户[" + username + "]进行登录验证...验证未通过,账户已锁定");
     85             request.setAttribute("message_login", "账户已锁定");
     86         }catch(ExcessiveAttemptsException eae){
     87             System.out.println("对用户[" + username + "]进行登录验证...验证未通过,错误次数过多");
     88             request.setAttribute("message_login", "用户名或密码错误次数过多");
     89         }catch(AuthenticationException ae){
     90             //通过处理Shiro的运行时AuthenticationException就可以控制用户登录失败或密码错误时的情景
     91             System.out.println("对用户[" + username + "]进行登录验证...验证未通过,堆栈轨迹如下");
     92             ae.printStackTrace();
     93             request.setAttribute("message_login", "用户名或密码不正确");
     94         }
     95         //验证是否登录成功
     96         if(currentUser.isAuthenticated()){
     97             System.out.println("用户[" + username + "]登录认证通过(这里可进行一些认证通过后的系统参数初始化操作)");
     98             return "main";
     99         }else{
    100             token.clear();
    101             return InternalResourceViewResolver.FORWARD_URL_PREFIX + "/";
    102         }
    103     }
    104     //属于admin角色
    105     //@RequiresRoles("admin")
    106     //必须同时属于user和admin角色
    107     @RequiresRoles({"user","admin"})
    108     //属于user或者admin之一;修改logical为OR 即可
    109     //@RequiresRoles(value={"user","admin"},logical=Logical.OR)
    110     @RequestMapping(value="/useRoles")
    111     public void requiresRoles(HttpServletRequest request, HttpServletResponse response){
    112         System.out.println("必须拥有指定角色");
    113     }
    114     //符合index:hello权限要求
    115     @RequiresPermissions("admin:manage")
    116     //必须同时复核index:hello和index:world权限要求
    117     //@RequiresPermissions({"index:hello","index:world"})
    118     //符合index:hello或index:world权限要求即可
    119     //@RequiresPermissions(value={"index:hello","index:world"},logical=Logical.OR)
    120     @RequestMapping(value="/useper")
    121     public void requiresPermissions(HttpServletRequest request, HttpServletResponse response){
    122         System.out.println("必须拥有指定权限");
    123     }
    124   /*  验证用户是否被记忆,user有两种含义:
    125     一种是成功登录的(subject.isAuthenticated() 结果为true);
    126     另外一种是被记忆的(subject.isRemembered()结果为true)。*/
    127     @RequiresUser
    128     @RequestMapping(value="/islogin")
    129     public void requiresUser(HttpServletRequest request, HttpServletResponse response){
    130         System.out.println("必须登录或者记住登录的");
    131     }
    132     //必须游客访问
    133     @RequiresGuest
    134     @RequestMapping(value="/isguest")
    135     public void requiresGuest(HttpServletRequest request, HttpServletResponse response){
    136         System.out.println("必须游客");
    137     }
    138 }
    View Code

    七、添加Realm代码

      1 package com.sh.realm;
      2 
      3 import org.apache.commons.lang3.builder.ReflectionToStringBuilder;
      4 import org.apache.commons.lang3.builder.ToStringStyle;
      5 import org.apache.shiro.SecurityUtils;
      6 import org.apache.shiro.authc.AuthenticationException;
      7 import org.apache.shiro.authc.AuthenticationInfo;
      8 import org.apache.shiro.authc.AuthenticationToken;
      9 import org.apache.shiro.authc.SimpleAuthenticationInfo;
     10 import org.apache.shiro.authc.UsernamePasswordToken;
     11 import org.apache.shiro.authz.AuthorizationInfo;
     12 import org.apache.shiro.authz.SimpleAuthorizationInfo;
     13 import org.apache.shiro.realm.AuthorizingRealm;
     14 import org.apache.shiro.session.Session;
     15 import org.apache.shiro.subject.PrincipalCollection;
     16 import org.apache.shiro.subject.Subject;
     17 
     18 /**
     19  * 自定义的指定Shiro验证用户登录的类
     20  * 这里定义了两个用户:admin(拥有admin角色和admin:manage权限)、user(无任何角色和权限)
     21  */
     22 public class MyRealm extends AuthorizingRealm {
     23     /**
     24      * 为当前登录的Subject授予角色和权限
     25      * -----------------------------------------------------------------------------------------------
     26      * 经测试:本例中该方法的调用时机为需授权资源被访问时
     27      * 经测试:并且每次访问需授权资源时都会执行该方法中的逻辑,这表明本例中默认并未启用AuthorizationCache
     28      * 个人感觉若使用了Spring3.1开始提供的ConcurrentMapCache支持,则可灵活决定是否启用AuthorizationCache
     29      * 比如说这里从数据库获取权限信息时,先去访问Spring3.1提供的缓存,而不使用Shior提供的AuthorizationCache
     30      * -----------------------------------------------------------------------------------------------
     31      */
     32     @Override
     33     protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals){
     34         //获取当前登录的用户名
     35         String currentUsername = (String)super.getAvailablePrincipal(principals);
     36         
     37 /*        UsernamePasswordToken token = new UsernamePasswordToken(currentUsername, "admin");
     38         SecurityUtils.getSubject().login(token);*/
     39         
     40         ////从数据库中获取当前登录用户的详细信息
     41         //List<String> roleList = new ArrayList<String>();
     42         //List<String> permissionList = new ArrayList<String>();
     43         //User user = userService.getByUsername(currentUsername);
     44         //if(null != user){
     45         //    //实体类User中包含有用户角色的实体类信息
     46         //    if(null!=user.getRoles() && user.getRoles().size()>0){
     47         //        //获取当前登录用户的角色
     48         //        for(Role role : user.getRoles()){
     49         //            roleList.add(role.getName());
     50         //            //实体类Role中包含有角色权限的实体类信息
     51         //            if(null!=role.getPermissions() && role.getPermissions().size()>0){
     52         //                //获取权限
     53         //                for(Permission pmss : role.getPermissions()){
     54         //                    if(StringUtils.isNotBlank(pmss.getPermission())){
     55         //                        permissionList.add(pmss.getPermission());
     56         //                    }
     57         //                }
     58         //            }
     59         //        }
     60         //    }
     61         //}else{
     62         //    throw new AuthorizationException();
     63         //}
     64         ////为当前用户设置角色和权限
     65         //SimpleAuthorizationInfo simpleAuthorInfo = new SimpleAuthorizationInfo();
     66         //simpleAuthorInfo.addRoles(roleList);
     67         //simpleAuthorInfo.addStringPermissions(permissionList);
     68         //实际中可能会像上面注释的那样,从数据库或缓存中取得用户的角色和权限信息
     69         SimpleAuthorizationInfo simpleAuthorInfo = new SimpleAuthorizationInfo();
     70         if(null!=currentUsername && "admin".equals(currentUsername)){
     71             //添加一个角色,不是配置意义上的添加,而是证明该用户拥有admin角色
     72             simpleAuthorInfo.addRole("admin");
     73             simpleAuthorInfo.addRole("user");
     74             //添加权限
     75             //simpleAuthorInfo.addStringPermission("admin:manage");
     76             //simpleAuthorInfo.addStringPermission("admin:add");
     77             simpleAuthorInfo.addStringPermission("*");//拥有所有权限
     78             System.out.println("已为用户[jadyer]赋予了[admin]角色和[admin:manage]权限");
     79             return simpleAuthorInfo;
     80         }
     81         if(null!=currentUsername && "fangke".equals(currentUsername)){
     82             System.out.println("当前用户[xuanyu]无授权(不需要为其赋予角色和权限)");
     83             return simpleAuthorInfo;
     84         }
     85         //若该方法什么都不做直接返回null的话
     86         //就会导致任何用户访问/admin/listUser.jsp时都会自动跳转到unauthorizedUrl指定的地址
     87         //详见applicationContext.xml中的<bean id="shiroFilter">的配置
     88         return null;
     89     }
     90 
     91     /**
     92      * 验证当前登录的Subject
     93      * 经测试:本例中该方法的调用时机为LoginController.login()方法中执行Subject.login()的时候
     94      */
     95     @Override
     96     protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authcToken) throws AuthenticationException {
     97         //获取基于用户名和密码的令牌
     98         //实际上这个authcToken是从LoginController里面currentUser.login(token)传过来的
     99         //两个token的引用都是一样的,本例中是:org.apache.shiro.authc.UsernamePasswordToken@33799a1e
    100         UsernamePasswordToken token = (UsernamePasswordToken)authcToken;
    101         System.out.print("验证当前Subject时获取到token:");
    102         System.out.println(ReflectionToStringBuilder.toString(token, ToStringStyle.MULTI_LINE_STYLE));
    103         //User user = userService.getByUsername(token.getUsername());
    104         //if(null != user){
    105         //    String username = user.getUsername();
    106         //    String password = user.getPassword();
    107         //    String nickname = user.getNickname();
    108         //    AuthenticationInfo authcInfo = new SimpleAuthenticationInfo(username, password, nickname);
    109         //    this.setSession("currentUser", user);
    110         //    return authcInfo;
    111         //}else{
    112         //    return null;
    113         //}
    114         //此处无需比对,比对的逻辑Shiro会做,我们只需返回一个和令牌相关的正确的验证信息
    115         //说白了就是第一个参数填登录用户名,第二个参数填合法的登录密码(可以是从数据库中取到的,本例中为了演示就硬编码了)
    116         //这样一来,在随后的登录页面上就只有这里指定的用户和密码才能通过验证
    117         if("admin".equals(token.getUsername())){
    118             AuthenticationInfo authcInfo = new SimpleAuthenticationInfo("admin", "admin", this.getName());
    119             this.setAuthenticationSession("admin");
    120             return authcInfo;
    121         }
    122         if("user".equals(token.getUsername())){
    123             AuthenticationInfo authcInfo = new SimpleAuthenticationInfo("user", "user", this.getName());
    124             this.setAuthenticationSession("user");
    125             return authcInfo;
    126         }
    127         //没有返回登录用户名对应的SimpleAuthenticationInfo对象时,就会在LoginController中抛出UnknownAccountException异常
    128         return null;
    129     }
    130 
    131     /**
    132      * 将一些数据放到ShiroSession中,以便于其它地方使用
    133      * 比如Controller里面,使用时直接用HttpSession.getAttribute(key)就可以取到
    134      */
    135     private void setAuthenticationSession(Object value){
    136         Subject currentUser = SecurityUtils.getSubject();
    137         if(null != currentUser){
    138             Session session = currentUser.getSession();
    139             System.out.println("当前Session超时时间为[" + session.getTimeout() + "]毫秒");//web.xml未配置session时间默认30分钟,配置了按照实际配置为准
    140             session.setTimeout(1000 * 60 * 60 * 2);
    141            // session.setTimeout(1000 * 60);//用户操作时时间顺延
    142             System.out.println("修改Session超时时间为[" + session.getTimeout() + "]毫秒");
    143             session.setAttribute("currentUser", value);
    144         }
    145     }
    146 }
    View Code

    Realm中实现两个方法:

    doGetAuthorizationInfo只要访问需要授权的内容,都会进入此方法,查找当前登录用户的权限

    doGetAuthenticationInfo调用shiro登录时,会执行此方法

    shiro有三种拦截方式,

    第一种是xml配置

    第二种是注解,我个人比较喜欢使用注解方式,感觉这样配置有针对性

    第三种是页面拦截,这种没有写,因为比较简单,百度一下全都有了

    本内容参考以下学习总结,感谢。http://jadyer.cn/2013/09/30/springmvc-shiro/

  • 相关阅读:
    JavaScript实现常见排序算法
    执行环境与作用域
    几种常见的三列布局,中间自适应,两边定宽
    常见的两列布局
    CodeAtlas For Sublime Text
    增加调用路径查找
    增加调用被调用个数隐喻
    sublime 插件
    分析大工程
    Jmeter 分布式测试
  • 原文地址:https://www.cnblogs.com/rb2010/p/8376912.html
Copyright © 2011-2022 走看看