shiro配置

    xiaoxiao2021-12-13  20

    1.依赖的jar包     <!-- shiro包 --> <dependency> <groupId>org.apache.shiro</groupId> <artifactId>shiro-web</artifactId> <version>1.2.2</version> </dependency> <dependency> <groupId>org.apache.shiro</groupId> <artifactId>shiro-spring</artifactId> <version>1.2.2</version> </dependency> <dependency> <groupId>org.apache.shiro</groupId> <artifactId>shiro-ehcache</artifactId> <version>1.2.2</version> </dependency> <dependency> <groupId>commons-lang</groupId> <artifactId>commons-lang</artifactId> <version>1.2.2</version> </dependency> 2.配置web.xml     <!-- 配置Shiro过滤器,先让Shiro过滤系统接收到的请求 --> <!-- 这里filter-name必须对应applicationContext.xml中定义的<bean id="shiroFilter"/> --> <!-- 使用[/*]匹配所有请求,保证所有的可控请求都经过Shiro的过滤 --> <!-- 通常会将此filter-mapping放置到最前面(即其他filter-mapping前面),以保证它是过滤器链中第一个起作用的 --> <filter> <filter-name>shiroFilter</filter-name> <filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class> <!-- <init-param> 该值缺省为false,表示生命周期由SpringApplicationContext管理,设置为true则表示由ServletContainer管理 <param-name>targetFilterLifecycle</param-name> <param-value>true</param-value> </init-param> --> </filter> <filter-mapping> <filter-name>shiroFilter</filter-name> <url-pattern>/*</url-pattern> </filter-mapping> 3.配置spring-shiro.xml文件 <?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:util="http://www.springframework.org/schema/util" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context" xmlns:aop="http://www.springframework.org/schema/aop" xsi:schemaLocation=" http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.0.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.0.xsd http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.0.xsd" default-autowire="byName" default-lazy-init="false">     <!--自定义认证 --> <bean id="myRealm" class="com.shawn.shiro.filter.MyRealm" /> <!-- Shiro默认会使用Servlet容器的Session,可通过sessionMode属性来指定使用Shiro原生Session -->         <!-- 即<property name="sessionMode" value="native"/>,详细说明见官方文档 -->         <!-- 这里主要是设置自定义的单Realm应用,若有多个Realm,可使用'realms'属性代替 -->     <bean id="securityManager" class="org.apache.shiro.web.mgt.DefaultWebSecurityManager"> <!--多realms配置 --> <property name="realms"> <list> <ref bean="myRealm" /> <!-- <ref bean="jdbcRealm" /> --> </list> </property> <!--<property name="realm" ref="jdbcRealm"/> --> <!--<property name="cacheManager" ref="cacheManager"/> --> </bean> <!-- 保证实现了Shiro内部lifecycle函数的bean执行 -->     <bean id="lifecycleBeanPostProcessor" class="org.apache.shiro.spring.LifecycleBeanPostProcessor" /> <!-- 数据库保存的密码是使用MD5算法加密的,所以这里需要配置一个密码匹配对象 --> <!-- <bean id="credentialsMatcher" class="org.apache.shiro.authc.credential.Md5CredentialsMatcher" /> --> <!-- 缓存管理 --> <!--<bean id="cacheManager" class="org.apache.shiro.cache.MemoryConstrainedCacheManager"/> --> <!-- Shiro主过滤器本身功能十分强大,其强大之处就在于它支持任何基于URL路径表达式的、自定义的过滤器的执行 Web应用中,Shiro可控制的Web请求必须经过Shiro主过滤器的拦截,Shiro对基于Spring的Web应用提供了完美的支持 --> <bean id="shiroFilter" class="org.apache.shiro.spring.web.ShiroFilterFactoryBean"> <!-- Shiro的核心安全接口,这个属性是必须的 --> <property name="securityManager" ref="securityManager" /> <!-- 要求登录时的链接(登录页面地址),非必须的属性,默认会自动寻找Web工程根目录下的"/login.jsp"页面 --> <property name="loginUrl" value="/login" /> <!-- 登录成功后要跳转的连接(本例中此属性用不到,因为登录成功后的处理逻辑在LoginController里硬编码) --> <!-- <property name="successUrl" value="/" ></property> --> <!-- 用户访问未对其授权的资源时,所显示的连接 --> <property name="unauthorizedUrl" value="/" /> <property name="filterChainDefinitions"> <value>                 /login=anon                 /favicon.ico=anon                 /logout = logout /**=authc /common/** = anon /dwz/** =anon </value> </property> </bean> <!-- 开启Shiro的注解(如@RequiresRoles,@RequiresPermissions),需借助SpringAOP扫描使用Shiro注解的类,  并在必要时进行安全逻辑验证 --> <!-- <bean class="org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator"></bean>  <bean class="org.apache.shiro.spring.security.interceptor.AuthorizationAttributeSourceAdvisor">  <property name="securityManager" ref="securityManager"></property> </bean> --> </beans> 4.安全过滤器的权限解释  过滤器名称     过滤器类                                                            描述 anon             org.apache.shiro.web.filter.authc.AnonymousFilter                    匿名过滤器 authc             org.apache.shiro.web.filter.authc.FormAuthenticationFilter            如果继续操作,需要做对应的表单验证否则不能通过 authcBasic           org.apache.shiro.web.filter.authc.BasicHttpAuthenticationFilter    基本http验证过滤,如果不通过,跳转屋登录页面 logout             org.apache.shiro.web.filter.authc.LogoutFilter                        登录退出过滤器 noSessionCreation    org.apache.shiro.web.filter.session.NoSessionCreationFilter        没有session创建过滤器 perms             org.apache.shiro.web.filter.authz.PermissionsAuthorizationFilter    权限过滤器 port             org.apache.shiro.web.filter.authz.PortFilter                        端口过滤器,可以设置是否是指定端口如果不是跳转到登录页面 rest             org.apache.shiro.web.filter.authz.HttpMethodPermissionFilter        http方法过滤器,可以指定如post不能进行访问等 roles             org.apache.shiro.web.filter.authz.RolesAuthorizationFilter            角色过滤器,判断当前用户是否指定角色 ssl                 org.apache.shiro.web.filter.authz.SslFilter                        请求需要通过ssl,如果不是跳转回登录页 user             org.apache.shiro.web.filter.authc.UserFilter                        如果访问一个已知用户,比如记住我功能,走这个过滤器 5.realm.java package com.shawn.shiro.filter; import org.apache.commons.lang.builder.ReflectionToStringBuilder; import org.apache.commons.lang.builder.ToStringStyle; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.apache.shiro.SecurityUtils; import org.apache.shiro.authc.AuthenticationException; import org.apache.shiro.authc.AuthenticationInfo; import org.apache.shiro.authc.AuthenticationToken; import org.apache.shiro.authc.SimpleAuthenticationInfo; import org.apache.shiro.authc.UsernamePasswordToken; import org.apache.shiro.authz.AuthorizationInfo; import org.apache.shiro.authz.SimpleAuthorizationInfo; import org.apache.shiro.realm.AuthorizingRealm; import org.apache.shiro.session.Session; import org.apache.shiro.subject.PrincipalCollection; import org.apache.shiro.subject.Subject; public class MyRealm extends AuthorizingRealm {   private static final Log Log = LogFactory.getLog(MyRealm.class);     /**       * 为当前登录的Subject授予角色和权限       * @see  经测试:本例中该方法的调用时机为需授权资源被访问时       * @see  经测试:并且每次访问需授权资源时都会执行该方法中的逻辑,这表明本例中默认并未启用AuthorizationCache       * @see  个人感觉若使用了Spring3.1开始提供的ConcurrentMapCache支持,则可灵活决定是否启用AuthorizationCache       * @see  比如说这里从数据库获取权限信息时,先去访问Spring3.1提供的缓存,而不使用Shior提供的AuthorizationCache       */       @Override       protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals){           Log.info("执行到这里了!!!!!");         //获取当前登录的用户名,等价于(String)principals.fromRealm(this.getName()).iterator().next()           String currentUsername = (String)super.getAvailablePrincipal(principals);   //      List<String> roleList = new ArrayList<String>();   //      List<String> permissionList = new ArrayList<String>();   //      //从数据库中获取当前登录用户的详细信息   //      User user = userService.getByUsername(currentUsername);   //      if(null != user){   //          //实体类User中包含有用户角色的实体类信息   //          if(null!=user.getRoles() && user.getRoles().size()>0){   //              //获取当前登录用户的角色   //              for(Role role : user.getRoles()){   //                  roleList.add(role.getName());   //                  //实体类Role中包含有角色权限的实体类信息   //                  if(null!=role.getPermissions() && role.getPermissions().size()>0){   //                      //获取权限   //                      for(Permission pmss : role.getPermissions()){   //                          if(!StringUtils.isEmpty(pmss.getPermission())){   //                              permissionList.add(pmss.getPermission());   //                          }   //                      }   //                  }   //              }   //          }   //      }else{   //          throw new AuthorizationException();   //      }   //      //为当前用户设置角色和权限   //      SimpleAuthorizationInfo simpleAuthorInfo = new SimpleAuthorizationInfo();   //      simpleAuthorInfo.addRoles(roleList);   //      simpleAuthorInfo.addStringPermissions(permissionList);           SimpleAuthorizationInfo simpleAuthorInfo = new SimpleAuthorizationInfo();           //实际中可能会像上面注释的那样从数据库取得           if(null!=currentUsername && "mike".equals(currentUsername)){               //添加一个角色,不是配置意义上的添加,而是证明该用户拥有admin角色                 simpleAuthorInfo.addRole("admin");               //添加权限               simpleAuthorInfo.addStringPermission("admin:manage");               System.out.println("已为用户[mike]赋予了[admin]角色和[admin:manage]权限");               return simpleAuthorInfo;           }         //若该方法什么都不做直接返回null的话,就会导致任何用户访问/admin/listUser.jsp时都会自动跳转到unauthorizedUrl指定的地址           //详见applicationContext.xml中的<bean id="shiroFilter">的配置           return null;       }                 /**       * 验证当前登录的Subject       * @see  经测试:本例中该方法的调用时机为LoginController.login()方法中执行Subject.login()时       */       @Override       protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authcToken) throws AuthenticationException {       Log.info("执行到这里了2!!!!!");         //获取基于用户名和密码的令牌           //实际上这个authcToken是从LoginController里面currentUser.login(token)传过来的           //两个token的引用都是一样的         UsernamePasswordToken token = (UsernamePasswordToken)authcToken;           System.out.println("验证当前Subject时获取到token为" + ReflectionToStringBuilder.toString(token, ToStringStyle.MULTI_LINE_STYLE));  //      User user = userService.getByUsername(token.getUsername());   //      if(null != user){   //          AuthenticationInfo authcInfo = new SimpleAuthenticationInfo(user.getUsername(), user.getPassword(), user.getNickname());   //          this.setSession("currentUser", user);   //          return authcInfo;   //      }else{   //          return null;   //      }           //此处无需比对,比对的逻辑Shiro会做,我们只需返回一个和令牌相关的正确的验证信息           //说白了就是第一个参数填登录用户名,第二个参数填合法的登录密码(可以是从数据库中取到的,本例中为了演示就硬编码了)           //这样一来,在随后的登录页面上就只有这里指定的用户和密码才能通过验证           if("mike".equals(token.getUsername())){               AuthenticationInfo authcInfo = new SimpleAuthenticationInfo("mike", "123456", this.getName());               this.setSession("currentUser", "mike");               return authcInfo;           }         //没有返回登录用户名对应的SimpleAuthenticationInfo对象时,就会在LoginController中抛出UnknownAccountException异常           return null;       }                     /**       * 将一些数据放到ShiroSession中,以便于其它地方使用       * @see  比如Controller,使用时直接用HttpSession.getAttribute(key)就可以取到       */       private void setSession(Object key, Object value){       Log.info("执行到这里了3!!!!!");         Subject currentUser = SecurityUtils.getSubject();           if(null != currentUser){               Session session = currentUser.getSession();               System.out.println("Session默认超时时间为[" + session.getTimeout() + "]毫秒");               if(null != session){                   session.setAttribute(key, value);               }           }       }   }
    转载请注明原文地址: https://ju.6miu.com/read-950081.html

    最新回复(0)