JAVA培训-Shiro安全框架

文章目录

Shiro

搭建

  • pom.xml: 导入库

    <dependency>
        <groupId>org.apache.shiro</groupId>
        <artifactId>shiro-all</artifactId>
        <version>1.4.1</version>
    </dependency>
    
  • web.xml: 过滤器

    <filter>
        <filter-name>iniShiroFilter</filter-name>
        <filter-class>org.apache.shiro.web.servlet.IniShiroFilter</filter-class>
    </filter>
    <filter-mapping>
        <filter-name>iniShiroFilter</filter-name>
        <url-pattern>/*</url-pattern>
    </filter-mapping>
    
  • xml: bean设置

    1. anno,任何人都可以访问;
    2. authc:必须是登录之后才能进行访问,不包括remember me;
    3. user:登录用户才可以访问,包含remember me;
    4. perms:指定过滤规则,这个一般是扩展使用,不会使用原生的
    <bean id="shiroFilter" class="org.apache.shiro.spring.web.ShiroFilterFactoryBean">
            <property name="securityManager" ref="securityManager" />
            <property name="loginUrl" value="/openid" />
            <property name="successUrl" value="/manage" />
            <property name="unauthorizedUrl" value="/openid" />
            <property name="filterChainDefinitions">
                <value>
                    /api/**=anon
                    /res/**=anon
                    /src/**=anon
                    /health/**=anon
                    /logout=authc
                    /openid=anon
                    /callback=anon
                    /=authc
                    /**=anon
                </value>
            </property>
        </bean>
    <bean id="securityManager" class="org.apache.shiro.web.mgt.DefaultWebSecurityManager">
            <!-- 继承AuthorizingRealm的类-->
            <property name="realm" ref="userRealm" />
        </bean>
    
  • Realm实现

    	@Component
    public class UserRealm extends AuthorizingRealm {
    	@Override
    	protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
    		//获取权限权限列表
    		 Iterator<String> iter = principals.fromRealm(getName()).iterator();
                    SimpleAuthorizationInfo info = new SimpleAuthorizationInfo();
                    info.addStringPermissions(Arrays.asList("q1","q2","q3"));   //数据库查询你结果
                    return info;
    	}
    	@Override
    	protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authcToken) throws AuthenticationException {
    		// 进行登陆操作
    		 try {
    	            UsernamePasswordToken token = (UsernamePasswordToken) authcToken;
    	            String name = token.getUsername();
    	            String password = new String(token.getPassword());
    	            if (true) {  //改为是否用户名密码正确
    	                return new SimpleAuthenticationInfo(name,password, getName());
    	            }
    	            return null;
    	        } catch (Exception e) {
    	            return null;
    	        }
    	}
    }
    

登录验证

	Subject sub = SecurityUtils.getSubject();
	UsernamePasswordToken token = new UsernamePasswordToken(username,password);
	 sub.login(token);    

权限检验

  • xml属性

    	 <property name="filterChainDefinitions">
    	            <value>
    	                /callback=anon
    	                /=authc
    	                /**=anon
    	            </value>
    	        </property>
    
  • annotation

    1. @RequiresAuthentication
      验证用户是否登录,等同于方法subject.isAuthenticated() 结果为true时。

    2. @RequiresUser
      验证用户是否被记忆,user有两种含义

      • 一种是成功登录的(subject.isAuthenticated() 结果为true);
      • 另外一种是被记忆的(subject.isRemembered()结果为true)。
    3. @RequiresGuest
      验证是否是一个guest的请求,与@RequiresUser完全相反。
      换言之,RequiresUser == !RequiresGuest。
      此时subject.getPrincipal() 结果为null.

    4. @RequiresRoles

      	@RequiresRoles("aRoleName");
      	 						 void someMethod();
      

      如果subject中有aRoleName角色才可以访问方法someMethod。如果没有这个权限则会抛出异常AuthorizationException。

    5. @RequiresPermissions

      	@RequiresPermissions({"file:read", "write:aFile.txt"} )   void
      		someMethod();
      

      要求subject中必须同时含有file:read和write:aFile.txt的权限才能执行方法someMethod()

  • tag标签

    1. <shiro:guest>
      	游客访问 <a href = "login.jsp"></a> 
      </shiro:guest>  
      
    2. user 标签:用户已经通过认证\记住我 登录后显示响应的内容

      <shiro:user>
      	欢迎[<shiro:principal/>];
      	登录 <a href = "logout">;
      	退出</a> 
      </shiro:user> 
      
    3. authenticated标签:用户身份验证通过,即 Subjec.login 登录成功 不是记住我登录的

       <shiro:authenticted>
      	用户[<shiro:principal/>] 
      	已身份验证通过 
      </shiro:authenticted>   
      
    4. notAuthenticated标签:用户未进行身份验证,即没有调用Subject.login进行登录,包括"记住我"也属于未进行身份验证

      <shiro:notAuthenticated>
      	未身份验证(包括"记住我")
      </shiro:notAuthenticated>
      
    5. principal 标签:显示用户身份信息,默认调用

      Subjec.getPrincipal()获取,即Primary Principal
      <shiro:principal property = "username"/>  
      
    6. hasRole标签:如果当前Subject有角色将显示body体内的内容

      <shiro:hashRole name = "admin">
      	用户[<shiro:principal/>] 拥有角色admin
      </shiro:hashRole>
      
    7. hasAnyRoles标签:如果Subject有任意一个角色(或的关系)将显示body体里的内容

      <shiro:hasAnyRoles name = "admin,user">
      	用户[<shiro:pricipal/>]拥有角色admin 或者 user
      </shiro:hasAnyRoles>
      
    8. lacksRole:如果当前 Subjec没有角色将显示body体内的内容

      <shiro:lacksRole name = "admin">
      	用户[<shiro:pricipal/>]没有角色admin 
      </shiro:lacksRole>   
      
    9. hashPermission:如果当前Subject有权限将显示body体内容

      <shiro:hashPermission name ="user:create">
      	用户[<shiro:pricipal/>] 拥有权限user:create 
      </shiro:hashPermission>   
      
    10. lacksPermission:如果当前Subject没有权限将显示body体内容

      <shiro:lacksPermission name = "org:create">
      	用户[<shiro:pricipal/>] 没有权限org:create 
      </shiro:lacksPermission>
      
  • 指定权限

    	Subject currentUser = SecurityUtils.getSubject();
    	    if (currentUser.hasRole("admin")) {
    	        logger.info("-----------啊啊啊啊--admin---------");
    	    }
    	    if (currentUser.hasRole("user")) {
    	        logger.info("-----------user---------");
    	    }
    
上一篇:36、Springboot 集成Shiro后 引入Swagger2被拦截的解决方案


下一篇:易用宝项目记录day5-shiro