shiro token 分析

Posted rigidwang

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了shiro token 分析相关的知识,希望对你有一定的参考价值。

1.ShiroConfig.java 定义匿名用户可以访问的资源

  filterMap.put("/webjars/**", "anon");
        filterMap.put("/druid/**", "anon");
        filterMap.put("/api/**", "anon");
        filterMap.put("/sys/login", "anon");
        filterMap.put("/**/*.css", "anon");
        filterMap.put("/**/*.js", "anon");
        filterMap.put("/**/*.html", "anon");
        filterMap.put("/fonts/**", "anon");
        filterMap.put("/plugins/**", "anon");
        filterMap.put("/swagger/**", "anon");
        filterMap.put("/favicon.ico", "anon");
        filterMap.put("/", "anon");
        filterMap.put("/**", "oauth2");           --除了anon,拦截其他所有请求

2.OAuth2Filter.java 基于shiro的全局过滤器

继承AuthenticatingFilter 实现createToken、isAccessAllowed、onAccessDenied、onLoginFailure等抽象方法

@Override
    protected boolean onAccessDenied(ServletRequest request, ServletResponse response) throws Exception {
        
        String token = getRequestToken((HttpServletRequest) request);
        if(StringUtils.isBlank(token)){
            HttpServletResponse httpResponse = (HttpServletResponse) response;
            String json = new Gson().toJson(R.error(HttpStatus.SC_UNAUTHORIZED, "invalid token"));
            httpResponse.getWriter().print(json);

            return false;
        }
        System.out.println("onAccessDenied-----------------------onAccessDenied");
        return executeLogin(request, response);
    }

如果成功获得token 则继续调用父类中executeLogin方法,此方法实现如下

protected boolean executeLogin(ServletRequest request, ServletResponse response) throws Exception {
        AuthenticationToken token = createToken(request, response);
        if (token == null) {
            String msg = "createToken method implementation returned null. A valid non-null AuthenticationToken " +
                    "must be created in order to execute a login attempt.";
            throw new IllegalStateException(msg);
        }
        try {
            Subject subject = getSubject(request, response);
            subject.login(token);
            return onLoginSuccess(token, subject, request, response);
        } catch (AuthenticationException e) {
            return onLoginFailure(token, e, request, response);
        }
    }

调用子类中的createToken方法获得token对象,将token对象赋值给shiro subject 对象,从而在后面的认证方法中获得token

3.将OAuth2Realm 注册到Shiro Seurity中,ShiroConfig.securityManager

技术分享
 1 package io.renren.config;
 2 
 3 import io.renren.modules.sys.oauth2.OAuth2Filter;
 4 import io.renren.modules.sys.oauth2.OAuth2Realm;
 5 import org.apache.shiro.mgt.SecurityManager;
 6 import org.apache.shiro.session.mgt.SessionManager;
 7 import org.apache.shiro.spring.LifecycleBeanPostProcessor;
 8 import org.apache.shiro.spring.security.interceptor.AuthorizationAttributeSourceAdvisor;
 9 import org.apache.shiro.spring.web.ShiroFilterFactoryBean;
10 import org.apache.shiro.web.mgt.DefaultWebSecurityManager;
11 import org.apache.shiro.web.session.mgt.DefaultWebSessionManager;
12 import org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator;
13 import org.springframework.context.annotation.Bean;
14 import org.springframework.context.annotation.Configuration;
15 
16 import javax.servlet.Filter;
17 import java.util.HashMap;
18 import java.util.LinkedHashMap;
19 import java.util.Map;
20 
21 
22 @Configuration
23 public class ShiroConfig {
24 
25     @Bean("sessionManager")
26     public SessionManager sessionManager(){
27         DefaultWebSessionManager sessionManager = new DefaultWebSessionManager();
28         sessionManager.setSessionValidationSchedulerEnabled(true);
29         sessionManager.setSessionIdCookieEnabled(false);
30         System.out.println("获得sessionManager:" + sessionManager);
31         return sessionManager;
32     }
33 
34     @Bean("securityManager")
35     public SecurityManager securityManager(OAuth2Realm oAuth2Realm, SessionManager sessionManager) {
36         DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager();
37         securityManager.setRealm(oAuth2Realm);
38         securityManager.setSessionManager(sessionManager);
39         System.out.println("获得SecurityManager:" + securityManager);
40         return securityManager;
41     }
42 
43     @Bean("shiroFilter")
44     public ShiroFilterFactoryBean shirFilter(SecurityManager securityManager) {
45         ShiroFilterFactoryBean shiroFilter = new ShiroFilterFactoryBean();
46         shiroFilter.setSecurityManager(securityManager);
47 
48         //oauth过滤
49         Map<String, Filter> filters = new HashMap<>();
50         filters.put("oauth2", new OAuth2Filter());
51         shiroFilter.setFilters(filters);
52 
53         Map<String, String> filterMap = new LinkedHashMap<>();
54         filterMap.put("/webjars/**", "anon");
55         filterMap.put("/druid/**", "anon");
56         filterMap.put("/api/**", "anon");
57         filterMap.put("/sys/login", "anon");
58         filterMap.put("/**/*.css", "anon");
59         filterMap.put("/**/*.js", "anon");
60         filterMap.put("/**/*.html", "anon");
61         filterMap.put("/fonts/**", "anon");
62         filterMap.put("/plugins/**", "anon");
63         filterMap.put("/swagger/**", "anon");
64         filterMap.put("/favicon.ico", "anon");
65         filterMap.put("/", "anon");
66         filterMap.put("/**", "oauth2");
67         shiroFilter.setFilterChainDefinitionMap(filterMap);
68         System.out.println("获得shiroFilter:" + shiroFilter);
69         return shiroFilter;
70     }
71 
72     @Bean("lifecycleBeanPostProcessor")
73     public LifecycleBeanPostProcessor lifecycleBeanPostProcessor() {
74         return new LifecycleBeanPostProcessor();
75     }
76 
77     @Bean
78     public DefaultAdvisorAutoProxyCreator defaultAdvisorAutoProxyCreator() {
79         DefaultAdvisorAutoProxyCreator proxyCreator = new DefaultAdvisorAutoProxyCreator();
80         proxyCreator.setProxyTargetClass(true);
81         return proxyCreator;
82     }
83 
84     @Bean
85     public AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor(SecurityManager securityManager) {
86         AuthorizationAttributeSourceAdvisor advisor = new AuthorizationAttributeSourceAdvisor();
87         advisor.setSecurityManager(securityManager);
88         return advisor;
89     }
90 
91 }
View Code

4.每次请求都会先调用OAuth2Realm中的doGetAuthenticationInfo方法验证token的合法性,然后再调用doGetAuthorizationInfo验证权限

5.通过common.js判断当前客户端是否缓存了token,如果没有则跳转至login.html

//登录token
var token = localStorage.getItem("token");
if(token == ‘null‘){
    parent.location.href = baseURL + ‘login.html‘;
}

6.登入页面输入用户名、密码之后 缓存token,并跳转至index.html

技术分享
login: function () {
            var data = "username="+vm.username+"&password="+vm.password;
            $.ajax({
                type: "POST",
                url: baseURL + "sys/login",
                data: data,
                dataType: "json",
                success: function(r){
                    if(r.code == 0){//登录成功
                        localStorage.setItem("token", r.token);
                        parent.location.href =‘index.html‘;
                    }else{
                        vm.error = true;
                        vm.errorMsg = r.msg;
                    }
                }
            });
        }
View Code

 

















以上是关于shiro token 分析的主要内容,如果未能解决你的问题,请参考以下文章

shiro认证过程

带你深入使用shiro,自定义token过滤器

带你深入使用shiro,自定义token过滤器

带你深入使用shiro,自定义token过滤器

带你深入使用shiro,自定义token过滤器

全栈编程系列SpringBoot整合Shiro(含KickoutSessionControlFilter并发在线人数控制以及不生效问题配置启动异常No SecurityManager...)(代码片段