shiro攔截認(rèn)證的全過程記錄
概述
Shiro是apache旗下一個開源安全框架(http://shiro.apache.org/),它將軟件系統(tǒng)的安全認(rèn)證相關(guān)的功能抽取出來,實現(xiàn)用戶身份認(rèn)證,權(quán)限授權(quán)、加密、會話管理等功能,組成了一個通用的安全認(rèn)證框架。使用shiro就可以非??焖俚耐瓿烧J(rèn)證、授權(quán)等功能的開發(fā),降低系統(tǒng)成本。
Shiro框架三大核心對象

說明:
1)Subject :主體對象,負(fù)責(zé)提交用戶認(rèn)證和授權(quán)信息。
2)SecurityManager:安全管理器,負(fù)責(zé)認(rèn)證,授權(quán)等業(yè)務(wù)實現(xiàn)。(核心)
3)Realm:領(lǐng)域?qū)ο?,?fù)責(zé)從數(shù)據(jù)層獲取業(yè)務(wù)數(shù)據(jù)。
shrio 攔截認(rèn)證全過程
?1.FilterRegistrationBean過濾注冊bean
@Bean
public FilterRegistrationBean shiroFilterRegistration() {
FilterRegistrationBean registration = new FilterRegistrationBean();
registration.setFilter(new DelegatingFilterProxy("shiroFilter"));
//該值缺省為false,表示生命周期由SpringApplicationContext管理,設(shè)置為true則表示由ServletContainer管理
registration.addInitParameter("targetFilterLifecycle", "true");
registration.setEnabled(true);
registration.setOrder(Integer.MAX_VALUE - 1);
registration.addUrlPatterns("/*");
return registration;
}
設(shè)置過濾的bean
2.shiroFilter 實際過濾配置bean
@Bean("shiroFilter")
public ShiroFilterFactoryBean shirFilter(SecurityManager securityManager) {
ShiroFilterFactoryBean shiroFilter = new ShiroFilterFactoryBean();
shiroFilter.setSecurityManager(securityManager);
//oauth過濾
Map<String, Filter> filters = new HashMap<>(10);
filters.put("oauth2", new Oauth2Filter());
shiroFilter.setFilters(filters);
Map<String, String> filterMap = new LinkedHashMap<>();
filterMap.put("/webjars/**", "anon");
filterMap.put("/druid/**", "anon");
filterMap.put("/login", "anon");
filterMap.put("/**", "oauth2");
shiroFilter.setFilterChainDefinitionMap(filterMap);
return shiroFilter;
}
配置oauth2Filter為過濾類 過濾對象處/webjars/** /druid/** /login 外的所有
3.過濾類Oauth2Filter 繼承 AuthenTicationFilter 重寫以下方法
/**
* 驗證是否有效token
* @param request re
* @param response res
* @return 驗證token
* @throws Exception
*/
@Override
protected boolean onAccessDenied(ServletRequest request, ServletResponse response) throws Exception {
//獲取請求token,如果token不存在,直接返回401
String token = getRequestToken((HttpServletRequest) request);
if(StringUtils.isBlank(token)){
HttpServletResponse httpResponse = (HttpServletResponse) response;
httpResponse.setContentType("application/json;charset=utf-8");
httpResponse.setHeader("Access-Control-Allow-Credentials", "true");
httpResponse.setHeader("Access-Control-Allow-Origin", HttpContextUtils.getOrigin());
String json = new Gson().toJson(new Result().error(ErrorCode.UNAUTHORIZED));
httpResponse.getWriter().print(json);
return false;
}
return executeLogin(request, response);
}
4.調(diào)用父類 executeLogin 進行登錄驗證
protected boolean executeLogin(ServletRequest request, ServletResponse response) throws Exception {
AuthenticationToken token = this.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);
} else {
try {
Subject subject = this.getSubject(request, response);
subject.login(token);
return this.onLoginSuccess(token, subject, request, response);
} catch (AuthenticationException var5) {
return this.onLoginFailure(token, var5, request, response);
}
}
}
5.subject.login(token); 進行登錄
login方法被DelegatingSubject重寫
public void login(AuthenticationToken token) throws AuthenticationException {
**
Subject subject = this.securityManager.login(this, token);
**
}
6.securityManager.login(this, token) login被DefaultSecurityManager
接下來幾步?jīng)]那么重要省略部分
7.ModularRealmAuthenticator AuthenticationInfo 授權(quán)信息獲取方法
protected AuthenticationInfo doAuthenticate(AuthenticationToken authenticationToken) throws AuthenticationException {
this.assertRealmsConfigured();
Collection<Realm> realms = this.getRealms();
return realms.size() == 1 ? this.doSingleRealmAuthentication((Realm)realms.iterator().next(), authenticationToken) : this.doMultiRealmAuthentication(realms, authenticationToken);
}
getRealms 獲取我們自己重寫的Realms類,主要用戶獲取用戶信息
8.接下來則進入我們自己寫的Realms類 我的類叫Oauth2Realm
/**
* 認(rèn)證(登錄時調(diào)用)
*/
@Override
protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
String accessToken = (String) token.getPrincipal();
//根據(jù)accessToken,查詢用戶信息
SysUserTokenEntity tokenEntity = shiroService.getByToken(accessToken);
//token失效
if(tokenEntity == null || tokenEntity.getExpireDate().getTime() < System.currentTimeMillis()){
throw new IncorrectCredentialsException(MessageUtils.getMessage(ErrorCode.TOKEN_INVALID));
}
//查詢用戶信息
SysUserEntity userEntity = shiroService.getUser(tokenEntity.getUserId());
//轉(zhuǎn)換成UserDetail對象
UserDetail userDetail = ConvertUtils.sourceToTarget(userEntity, UserDetail.class);
//獲取用戶對應(yīng)的部門數(shù)據(jù)權(quán)限
List<Long> deptIdList = shiroService.getDataScopeList(userDetail.getId());
userDetail.setDeptIdList(deptIdList);
//賬號鎖定
if(userDetail.getStatus() == 0){
throw new LockedAccountException(MessageUtils.getMessage(ErrorCode.ACCOUNT_LOCK));
}
SimpleAuthenticationInfo info = new SimpleAuthenticationInfo(userDetail, accessToken, getName());
return info;
}
負(fù)責(zé)獲取用戶信息的方法
這并不是登錄的過程,而是授權(quán)過濾的過程,通過token到數(shù)據(jù)庫查詢是否有這個用戶,且沒有過期,則證明已經(jīng)登錄。
總結(jié)
到此這篇關(guān)于shrio攔截認(rèn)證的文章就介紹到這了,更多相關(guān)shrio攔截認(rèn)證內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Java中JMM與volatile關(guān)鍵字的學(xué)習(xí)
這篇文章主要介紹了通過實例解析JMM和Volatile關(guān)鍵字的學(xué)習(xí),文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友可以參考下2021-09-09
Java 字符串轉(zhuǎn)float運算 float轉(zhuǎn)字符串的方法
今天小編就為大家分享一篇Java 字符串轉(zhuǎn)float運算 float轉(zhuǎn)字符串的方法,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧2018-07-07
Spring的@Transactional注解使用詳細(xì)解析
這篇文章主要介紹了Spring的@Transactional注解使用詳細(xì)解析,@Transactional 注解相信大家并不陌生,平時開發(fā)中很常用的一個注解,它能保證方法內(nèi)多個數(shù)據(jù)庫操作要么同時成功、要么同時失敗,需要的朋友可以參考下2023-11-11
ElasticSearch不停機重建索引延伸思考及優(yōu)化詳解
這篇文章主要為大家介紹了ElasticSearch不停機重建索引延伸思考及優(yōu)化詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪2023-02-02
Java/Android 獲取網(wǎng)絡(luò)重定向文件的真實URL的示例代碼
本篇文章主要介紹了Java/Android 獲取網(wǎng)絡(luò)重定向文件的真實URL的示例代碼,具有一定的參考價值,感興趣的小伙伴們可以參考一下2017-11-11
logback的ShutdownHook關(guān)閉原理解析
這篇文章主要為大家介紹了logback的ShutdownHook關(guān)閉原理源碼解讀,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪2023-11-11

