springboot集成shiro遭遇自定義filter異常的解決_第1頁
springboot集成shiro遭遇自定義filter異常的解決_第2頁
springboot集成shiro遭遇自定義filter異常的解決_第3頁
springboot集成shiro遭遇自定義filter異常的解決_第4頁
springboot集成shiro遭遇自定義filter異常的解決_第5頁
已閱讀5頁,還剩15頁未讀, 繼續(xù)免費閱讀

下載本文檔

版權(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. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

最新文檔

評論

0/150

提交評論