版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進行舉報或認領(lǐng)
文檔簡介
第springboot集成shiro遭遇自定義filter異常的解決目錄springboot集成shiro遭遇自定義filter異常1、用maven添加shiro2、配置shiro3、實現(xiàn)自定義的Realm、filter、SubjectFactory等4、重點記錄filter配置中出現(xiàn)的問題5、解決方案shiro自定義異常無效
springboot集成shiro遭遇自定義filter異常
首先簡述springboot使用maven集成shiro
1、用maven添加shiro
!--shiro--
dependency
groupIdorg.apache.shiro/groupId
artifactIdshiro-web/artifactId
version1.4.0/version
/dependency
dependency
groupIdorg.apache.shiro/groupId
artifactIdshiro-spring/artifactId
version1.4.0/version
/dependency
2、配置shiro
importelligent.log.service.QueryPermissionService;
importelligent.log.service.shiro.authc.AccountSubjectFactory;
importelligent.log.service.shiro.filter.AuthenticatedFilter;
importelligent.log.service.shiro.filter.QueryLimitFiter;
importelligent.log.service.shiro.realm.AccountRealm;
importorg.apache.shiro.cache.CacheManager;
importorg.apache.shiro.cache.MemoryConstrainedCacheManager;
importorg.apache.shiro.codec.Base64;
importorg.apache.shiro.session.mgt.SessionManager;
importorg.apache.shiro.spring.LifecycleBeanPostProcessor;
importerceptor.AuthorizationAttributeSourceAdvisor;
importorg.apache.shiro.spring.web.ShiroFilterFactoryBean;
importorg.apache.shiro.web.mgt.CookieRememberMeManager;
importorg.apache.shiro.web.mgt.DefaultWebSecurityManager;
importorg.apache.shiro.web.servlet.Cookie;
importorg.apache.shiro.web.servlet.ShiroHttpSession;
importorg.apache.shiro.web.servlet.SimpleCookie;
importorg.apache.shiro.web.session.mgt.DefaultWebSessionManager;
importorg.springframework.beans.factory.config.MethodInvokingFactoryBean;
importorg.springframework.context.annotation.Bean;
importorg.springframework.context.annotation.Configuration;
importjavax.annotation.Resource;
importjavax.servlet.Filter;
importjava.util.HashMap;
importjava.util.LinkedHashMap;
importjava.util.Map;
*shiro權(quán)限管理的配置
@Configuration
publicclassShiroConfig{
@Bean
publicAccountSubjectFactoryaccountSubjectFactory(){
returnnewAccountSubjectFactory();
*安全管理器
@Bean
publicDefaultWebSecurityManagersecurityManager(CookieRememberMeManagerrememberMeManager,CacheManagercacheShiroManager,SessionManagersessionManager){
DefaultWebSecurityManagersecurityManager=newDefaultWebSecurityManager();
securityManager.setRealm(this.shiroAccountRealm());
securityManager.setCacheManager(cacheShiroManager);
securityManager.setRememberMeManager(rememberMeManager);
securityManager.setSessionManager(sessionManager);
securityManager.setSubjectFactory(this.accountSubjectFactory());
returnsecurityManager;
*session管理器(單機環(huán)境)
@Bean
publicDefaultWebSessionManagerdefaultWebSessionManager(CacheManagercacheShiroManager){
DefaultWebSessionManagersessionManager=newDefaultWebSessionManager();
sessionManager.setCacheManager(cacheShiroManager);
sessionManager.setSessionValidationInterval(1800*1000);
sessionManager.setGlobalSessionTimeout(900*1000);
sessionManager.setDeleteInvalidSessions(true);
sessionManager.setSessionValidationSchedulerEnabled(true);
Cookiecookie=newSimpleCookie(ShiroHttpSession.DEFAULT_SESSION_ID_NAME);
cookie.setName("shiroCookie");
cookie.setHttpOnly(true);
sessionManager.setSessionIdCookie(cookie);
returnsessionManager;
*緩存管理器使用Ehcache實現(xiàn)
@Bean
publicCacheManagergetCacheShiroManager(){
returnnewMemoryConstrainedCacheManager();
*項目自定義的Realm
@Bean
publicAccountRealmshiroAccountRealm(){
returnnewAccountRealm();
*rememberMe管理器,cipherKey生成見{@codeBase64Test.java}
@Bean
publicCookieRememberMeManagerrememberMeManager(SimpleCookierememberMeCookie){
CookieRememberMeManagermanager=newCookieRememberMeManager();
manager.setCipherKey(Base64.decode("Z3VucwAAAAAAAAAAAAAAAA=="));
manager.setCookie(rememberMeCookie);
returnmanager;
*記住密碼Cookie
@Bean
publicSimpleCookierememberMeCookie(){
SimpleCookiesimpleCookie=newSimpleCookie("rememberMe");
simpleCookie.setHttpOnly(true);
simpleCookie.setMaxAge(7*24*60*60);//7天
returnsimpleCookie;
*Shiro的過濾器鏈
@Bean
publicShiroFilterFactoryBeanshiroFilter(DefaultWebSecurityManagersecurityManager,CollectionPropertiesConfigcollectionPropertiesConfig,QueryPermissionServicequeryPermissionService){
ShiroFilterFactoryBeanshiroFilter=newShiroFilterFactoryBean();
shiroFilter.setSecurityManager(securityManager);
*默認的登陸訪問url
shiroFilter.setLoginUrl("/login");
*登陸成功后跳轉(zhuǎn)的url
shiroFilter.setSuccessUrl("/");
*沒有權(quán)限跳轉(zhuǎn)的url
shiroFilter.setUnauthorizedUrl("/error/reject.html");
*覆蓋默認的user攔截器(默認攔截器解決不了ajax請求session超時的問題,若有更好的辦法請及時反饋作者)
HashMapString,FiltermyFilters=newHashMap();
myFilters.put("query",newQueryLimitFiter(queryPermissionService));
myFilters.put("authc",newAuthenticatedFilter());
shiroFilter.setFilters(myFilters);
*配置shiro攔截器鏈
*anon不需要認證
*authc需要認證
*user驗證通過或RememberMe登錄的都可以
*當應(yīng)用開啟了rememberMe時,用戶下次訪問時可以是一個user,但不會是authc,因為authc是需要重新認證的
*順序從上到下,優(yōu)先級依次降低
MapString,StringhashMap=newLinkedHashMap();
hashMap.put("/login","anon");
hashMap.put("/","authc");
hashMap.put("/user*","authc");
hashMap.put("/user/**","authc");
hashMap.put("/post/**","authc");
hashMap.put("/admin","authc,perms[admin]");
hashMap.put("/admin/**","authc,perms[admin]");
for(Stringuri:collectionPropertiesConfig.getQueryLogUrls()){
hashMap.put(uri,"query");
shiroFilter.setFilterChainDefinitionMap(hashMap);
returnshiroFilter;
*在方法中注入securityManager,進行代理控制
@Bean
publicMethodInvokingFactoryBeanmethodInvokingFactoryBean(DefaultWebSecurityManagersecurityManager){
MethodInvokingFactoryBeanbean=newMethodInvokingFactoryBean();
bean.setStaticMethod("org.apache.shiro.SecurityUtils.setSecurityManager");
bean.setArguments(newObject[]{securityManager});
returnbean;
*Shiro生命周期處理器:
*用于在實現(xiàn)了Initializable接口的Shirobean初始化時調(diào)用Initializable接口回調(diào)(例如:UserRealm)
*在實現(xiàn)了Destroyable接口的Shirobean銷毀時調(diào)用Destroyable接口回調(diào)(例如:DefaultSecurityManager)
@Bean
publicLifecycleBeanPostProcessorlifecycleBeanPostProcessor(){
returnnewLifecycleBeanPostProcessor();
*啟用shrio授權(quán)注解攔截方式,AOP式方法級權(quán)限檢查
@Bean
publicAuthorizationAttributeSourceAdvisorauthorizationAttributeSourceAdvisor(DefaultWebSecurityManagersecurityManager){
AuthorizationAttributeSourceAdvisorauthorizationAttributeSourceAdvisor=
newAuthorizationAttributeSourceAdvisor();
authorizationAttributeSourceAdvisor.setSecurityManager(securityManager);
returnauthorizationAttributeSourceAdvisor;
}
3、實現(xiàn)自定義的Realm、filter、SubjectFactory等
importelligent.log.model.sysmodel.OrganizationUser;
importorg.apache.shiro.authc.SimpleAuthenticationInfo;
publicclassAccountAuthenticationInfoextendsSimpleAuthenticationInfo{
privatestaticfinallongserialVersionUID=3405356595200877071L;
privateOrganizationUserprofile;
publicAccountAuthenticationInfo(){
publicAccountAuthenticationInfo(Objectprincipal,Objectcredentials,StringrealmName){
super(principal,credentials,realmName);
publicOrganizationUsergetProfile(){
returnprofile;
publicvoidsetProfile(OrganizationUserprofile){
file=profile;
importelligent.log.model.sysmodel.OrganizationUser;
importorg.apache.shiro.mgt.SecurityManager;
importorg.apache.shiro.session.Session;
importorg.apache.shiro.subject.PrincipalCollection;
importorg.apache.shiro.web.subject.support.WebDelegatingSubject;
importjavax.servlet.ServletRequest;
importjavax.servlet.ServletResponse;
publicclassAccountSubjectextendsWebDelegatingSubject{
privateOrganizationUserprofile;
publicAccountSubject(PrincipalCollectionprincipals,booleanauthenticated,Stringhost,Sessionsession,
booleansessionEnabled,ServletRequestrequest,ServletResponseresponse,SecurityManagersecurityManager,OrganizationUserprofile){
super(principals,authenticated,host,session,sessionEnabled,request,response,securityManager);
file=profile;
publicStringgetUsername(){
returngetPrincipal().toString();
publicOrganizationUsergetProfile(){
returnprofile;
importelligent.log.model.sysmodel.OrganizationUser;
importelligent.log.service.UserService;
importorg.apache.shiro.authc.AuthenticationInfo;
importorg.apache.shiro.mgt.SubjectFactory;
importorg.apache.shiro.session.Session;
importorg.apache.shiro.subject.Subject;
importorg.apache.shiro.subject.SubjectContext;
importorg.apache.shiro.web.subject.WebSubjectContext;
importorg.springframework.beans.factory.annotation.Autowired;
publicclassAccountSubjectFactoryimplementsSubjectFactory{
@Autowired
privateUserServiceuserService;
@Override
publicSubjectcreateSubject(SubjectContextcontext){
WebSubjectContextwsc=(WebSubjectContext)context;
AuthenticationInfoinfo=wsc.getAuthenticationInfo();
OrganizationUserprofile=null;
AccountSubjectsubject=null;
if(infoinstanceofAccountAuthenticationInfo){
profile=((AccountAuthenticationInfo)info).getProfile();
subject=doCreate(wsc,profile);
subject.getSession(true).setAttribute("profile",profile);
}else{
Sessionsession=wsc.getSession();
if(session!=null){
profile=(OrganizationUser)session.getAttribute("profile");
subject=doCreate(wsc,profile);
booleanisRemembered=subject.isRemembered();
if(session==null){
wsc.setSessionCreationEnabled(true);
subject.getSession(true);
if(isRememberedprofile==null){
Objectusername=subject.getPrincipal();
profile=userService.getUserByName((String)username);
subject.getSession(true).setTimeout(30*60*1000);
subject.getSession(true).setAttribute("profile",profile);
returndoCreate(wsc,profile);
privateAccountSubjectdoCreate(WebSubjectContextwsc,OrganizationUserprofile){
returnnewAccountSubject(wsc.resolvePrincipals(),wsc.resolveAuthenticated(),wsc.resolveHost(),
wsc.resolveSession(),wsc.isSessionCreationEnabled(),wsc.resolveServletRequest(),
wsc.resolveServletResponse(),wsc.resolveSecurityManager(),profile);
importorg.apache.shiro.authc.AuthenticationToken;
publicclassAccountTokenimplementsAuthenticationToken{
privatestaticfinallongserialVersionUID=1L;
privatelongid;
privateStringusername;
publicAccountToken(){
publicAccountToken(longid,finalStringusername){
this(id,username,username);
publicAccountToken(longid,finalStringusername,Stringnickname){
this.id=id;
this.username=username;
@Override
publicObjectgetPrincipal(){
returnusername;
@Override
publicObjectgetCredentials(){
returnnull;
publiclonggetId(){
returnid;
publicvoidsetId(longid){
this.id=id;
publicStringgetUsername(){
returnusername;
publicvoidsetUsername(Stringusername){
this.username=username;
importmons.lang3.StringUtils;
importorg.apache.shiro.SecurityUtils;
importorg.apache.shiro.subject.Subject;
importorg.apache.shiro.web.servlet.OncePerRequestFilter;
importorg.apache.shiro.web.util.WebUtils;
importorg.slf4j.Logger;
importorg.slf4j.LoggerFactory;
importjavax.servlet.FilterChain;
importjavax.servlet.ServletException;
importjavax.servlet.ServletRequest;
importjavax.servlet.ServletResponse;
importjavax.servlet.http.HttpServletRequest;
importjava.io.IOException;
importjava.util.Formatter;
*@version1.0.0
publicclassAuthenticatedFilterextendsOncePerRequestFilter{
privateLoggerLOG=LoggerFactory.getLogger(AuthenticatedFilter.class);
privatestaticfinalStringJS="scripttype='text/javascript'varwp=window.parent;if(wp!=null){while(wp.parentwp.parent!==wp){wp=wp.parent;}wp.location.href='%1$s';}else{window.location.href='%1$s';}/script
privateStringloginUrl="/login";
@Override
protectedvoiddoFilterInternal(ServletRequestrequest,ServletResponseresponse,FilterChainchain)
throwsServletException,IOException{
LOG.info("開始權(quán)限驗證");
Subjectsubject=SecurityUtils.getSubject();
if(subject.isAuthenticated()){
chain.doFilter(request,response);
}else{
identifyGuest(subject,request,response,chain);
protectedvoididentifyGuest(Subjectsubject,ServletRequestrequest,ServletResponseresponse,FilterChainchain)
throwsServletException,IOException{
redirectLogin(request,response);
protectedvoidredirectLogin(ServletRequestrequest,ServletResponseresponse)throwsIOException{
WebUtils.saveRequest(request);
Stringpath=WebUtils.getContextPath((HttpServletRequest)request);
Stringurl=loginUrl;
if(StringUtils.isNotBlank(path)path.length()1){
url=path+url;
if(isAjaxRequest((HttpServletRequest)request)){
response.setContentType("application/json;charset=UTF-8");
response.getWriter().print("您還沒有登錄!");
}else{
response.getWriter().write(newFormatter().format(JS,url).toString());
publicStringgetLoginUrl(){
returnloginUrl;
publicvoidsetLoginUrl(StringloginUrl){
this.loginUrl=loginUrl;
*判斷是否為Ajax請求功能詳細描述
*@paramrequest
*@return是true,否false
*@see[類、類#方法、類#成員]
publicstaticbooleanisAjaxRequest(HttpServletRequestrequest){
Stringheader=request.getHeader("X-Requested-With");
if(header!=null"XMLHttpRequest".equals(header))
returntrue;
else
returnfalse;
importelligent.log.service.QueryPermissionService;
importmons.lang.StringUtils;
importorg.apache.shiro.web.servlet.AbstractFilter;
importorg.apache.shiro.web.servlet.ServletContextSupport;
importorg.slf4j.Logger;
importorg.slf4j.LoggerFactory;
importjavax.servlet.*;
importjavax.servlet.http.HttpServletRequest;
importjava.io.IOException;
publicclassQueryLimitFiterextendsServletContextSupportimplementsFilter{
privateQueryPermissionServicequeryPermissionService;
privatestaticfinaltransientLoggerlog=LoggerFactory.getLogger(AbstractFilter.class);
protectedFilterConfigfilterConfig;
publicQueryLimitFiter(QueryPermissionServicequeryPermissionService){
this.queryPermissionService=queryPermissionService;
publicFilterConfiggetFilterConfig(){
returnthis.filterConfig;
publicvoidsetFilterConfig(FilterConfigfilterConfig){
this.filterConfig=filterConfig;
this.setServletContext(filterConfig.getServletContext());
protectedStringgetInitParam(StringparamName){
FilterConfigconfig=this.getFilterConfig();
returnconfig!=nullorg.apache.shiro.util.StringUtils.clean(config.getInitParameter(paramName)):null;
publicfinalvoidinit(FilterConfigfilterConfig)throwsServletException{
this.setFilterConfig(filterConfig);
try{
this.onFilterConfigSet();
}catch(Exceptionvar3){
if(var3instanceofServletException){
throw(ServletException)var3;
}else{
if(log.isErrorEnabled()){
log.error("UnabletostartFilter:["+var3.getMessage()+"].",var3);
thrownewServletException(var3);
protectedvoidonFilterConfigSet()throwsException{
publicvoiddestroy(){
@Override
publicvoiddoFilter(ServletRequestservletRequest,ServletResponseservletResponse,FilterChainfilterChain)throwsIOException,ServletException{
if(isAccessAllowed(servletRequest,servletResponse)){
filterChain.doFilter(servletRequest,servletResponse);
}else{
servletResponse.setContentType("application/json;charset=UTF-8");
servletResponse.getWriter().print("不允許查詢!");
protectedbooleanisAccessAllowed(ServletRequestservletRequest,ServletResponseservletResponse){
HttpServletRequestrequest=(HttpServletRequest)servletRequest;
StringhallCode=request.getParameter("guanhao");
Stringuri=request.getRequestURI();
System.out.println(uri);
//if(collectionPropertiesConfig.getQueryLogUrls().contains(uri)){
try{
if(StringUtils.isEmpty(hallCode)){
servletResponse.setContentType("application/json;charset=UTF-8");
servletResponse.getWriter().print("需要輸入館號!");
returnfalse;
if(queryPermissionService.permit(hallCode)){
returntrue;
}else{
servletResponse.setContentType("application/json;charset=UTF-8");
servletResponse.getWriter().print("你沒有權(quán)限查詢此館!");
returnfalse;
}catch(Exceptione){
e.printStackTrace();
returnfalse;
importelligent.log.model.sysmodel.OrganizationPrivilege;
importelligent.log.model.sysmodel.OrganizationResources;
importelligent.log.model.sysmodel.OrganizationUser;
importelligent.log.service.RoleService;
importelligent.log.service.UserService;
importelligent.log.service.shiro.authc.AccountAuthenticationInfo;
importorg.apache.shiro.authc.*;
importorg.apache.shiro.authc.credential.AllowAllCredentialsMatcher;
importorg.apache.shiro.authz.AuthorizationInfo;
importorg.apache.shiro.authz.SimpleAuthorizationInfo;
importorg.apache.shiro.realm.AuthorizingRealm;
importorg.apache.shiro.subject.PrincipalCollection;
importorg.springframework.beans.factory.annotation.Autowired;
importjavax.annotation.Resource;
importjava.util.List;
publicclassAccountRealmextendsAuthorizingRealm{
@Autowired
privateUserServiceuserService;
@Autowired
privateRoleServiceuserRoleService;
publicAccountRealm(){
super(newAllowAllCredentialsMatcher());
setAuthenticationTokenClass(UsernamePasswordToken.class);
@Override
protectedAuthorizationInfodoGetAuthorizationInfo(PrincipalCollectionprincipals){
Stringusername=(String)principals.fromRealm(getName()).iterator().next();
if(username!=null){
OrganizationUseruser=userService.getUserByName(username);
if(user!=null){
SimpleAuthorizationInfoinfo=newSimpleAuthorizationInfo();
OrganizationPrivilegerole=userRoleService.getRole(user.getPrivilegeId());
ListOrganizationResourcesroleResources=userRoleService.
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負責。
- 6. 下載文件中如有侵權(quán)或不適當內(nèi)容,請與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 2026年海洋能發(fā)電公司保密工作管理制度
- 2026春貴州貴陽市觀山湖區(qū)第七中學招臨聘教師6人備考題庫附答案詳解(黃金題型)
- 2025-2030中國筋膜槍行業(yè)銷售前景與營銷推廣渠道分析研究報告
- 2026江蘇南京大學化學學院助理招聘備考題庫含答案詳解(預(yù)熱題)
- 2026江蘇南京大學化學學院助理招聘備考題庫附參考答案詳解(研優(yōu)卷)
- (2025年)《人體生理學》第一章緒論復(fù)習測試題及答案
- (2025年)《醫(yī)院感染診斷標準及職業(yè)暴露培訓試題》試題(附答案)
- (2025年)商業(yè)銀行經(jīng)營管理期末復(fù)習試題附答案
- (2025年)建筑施工入場考試題及答案
- 2026江蘇南京大學化學學院博士后招聘備考題庫含答案詳解(考試直接用)
- 深圳大疆在線測評行測題庫
- 金屬廠生產(chǎn)制度
- 2026安徽淮北市特種設(shè)備監(jiān)督檢驗中心招聘專業(yè)技術(shù)人員4人參考題庫及答案1套
- 2025年航空行業(yè)空客智能制造報告
- 蒙牛乳業(yè)股份有限公司盈利能力分析
- 2025民航西藏空管中心社會招聘14人(第1期)筆試參考題庫附帶答案詳解(3卷合一版)
- (新教材)2026年人教版八年級下冊數(shù)學 21.2.1 平行四邊形及其性質(zhì) 課件
- 設(shè)備保養(yǎng)維護規(guī)程
- 2025年東營中考物理真題及答案
- DL-T+5860-2023+電化學儲能電站可行性研究報告內(nèi)容深度規(guī)定
- GB/T 46425-2025煤矸石山生態(tài)修復(fù)技術(shù)規(guī)范
評論
0/150
提交評論