Spring security權(quán)限配置與使用大全
簡介
Spring Security 是為了基于Spring的應(yīng)用程序提供的聲明式安全保護(hù)的安全性框架。Spring Security 提供了完整的安全性解決方案,它能夠在Web請(qǐng)求級(jí)別和方法調(diào)用級(jí)別處理身份認(rèn)證和授權(quán)。因?yàn)榛赟pring框架,所以SPring Security充分使用了一覽注入和面向切面技術(shù)。
Spring Security 本質(zhì)上是借助一系列的 Servlet Filter來提供各種安全性功能,但這并不需要我們手動(dòng)去添加或者創(chuàng)建多個(gè)Filter。實(shí)際上,我們僅需要配置一個(gè)Filter即可。
DelegatingFilterProxy 是一個(gè)特殊的Filter,他本身并沒有做太多工作,而是將工作委托給了一個(gè)注入到Spring應(yīng)用上下文的Filter實(shí)現(xiàn)類。
在本例中,主要講解spring-security的配置與使用,實(shí)現(xiàn)方式為:
1.將用戶、權(quán)限、資源(url)采用數(shù)據(jù)庫存儲(chǔ)
2.自定義過濾器,代替原有的 FilterSecurityInterceptor
3.自定義實(shí)現(xiàn) UserDetailsService、Filter、AccessDecisionManager和FilterInvocationSecurityMetadataSource并在配置文件進(jìn)行相應(yīng)的配置
4.Spring-seculity在自定義用戶驗(yàn)證的類加載必須早于Controller層創(chuàng)建
1.配置Spring-seculity.xml
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:security="http://www.springframework.org/schema/security" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/security http://www.springframework.org/schema/security/spring-security.xsd"> <security:http security="none" pattern="/login.jsp"/> <security:http security="none" pattern="/plugins/**"/> <security:http security="none" pattern="/css/**"/> <security:http security="none" pattern="/css/style.css"/> <security:http security="none" pattern="/img/**"/> <security:http security="none" pattern="/filer.jsp"/> <security:http security="none" pattern="/favicon.ico"/> <security:http auto-config="true" use-expressions="false"> <!--優(yōu)先加載MyFilter自定義過濾器--> <security:custom-filter before="FILTER_SECURITY_INTERCEPTOR" ref="myFilter"/> <!--固定用戶攔截--> <!--<security:intercept-url pattern="/**" access="ROLE_USER" />--> <!--用戶賬戶和密碼表單驗(yàn)證--> <!--login-page="攔截跳轉(zhuǎn)頁面" login-processing-url="用戶登陸驗(yàn)證路徑" user-paramter=“頁面賬戶名字” password-parameter=“頁面密碼” authentication-failure-url=“登陸失敗跳轉(zhuǎn)頁面” default-target-rul=“登陸成功跳轉(zhuǎn)頁面” --> <security:form-login login-page="/login.jsp" login-processing-url="/login" username-parameter="username" password-parameter="password" authentication-failure-url="/filer.jsp" default-target-url="/jsp/all-admin-index.jsp"/> <!--用戶退出登陸 --> <security:logout invalidate-session="true" logout-url="/logout" logout-success-url="/login.jsp"/> <!--禁止跨域請(qǐng)求--> <security:csrf disabled="true"/> </security:http> <bean id="myFilter" class="filter.MyFilter"/> <bean id="userinfo" class="ssm.service.UserinfoService"/> <!--固定用戶賬戶和密碼的驗(yàn)證--> <security:authentication-manager > <security:authentication-provider user-service-ref="userinfo"> <!--固定用戶名跟密碼--> <!-- <security:user-service>--> <!-- <security:user name="user" password="{noop}user"--> <!-- authorities="ROLE_USER" />--> <!-- </security:user-service>--> </security:authentication-provider> </security:authentication-manager> </beans>
2.配置Web.xml
<?xml version="1.0" encoding="UTF-8"?> <web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd" version="4.0"> <display-name>ssm-web</display-name> <welcome-file-list> <welcome-file>all-admin-login.jsp</welcome-file> <welcome-file>index.htm</welcome-file> <welcome-file>index.jsp</welcome-file> <welcome-file>default.html</welcome-file> <welcome-file>default.htm</welcome-file> <welcome-file>default.jsp</welcome-file> </welcome-file-list> <!--全局監(jiān)聽變量--> <context-param> <param-name>contextConfigLocation</param-name> <param-value>classpath:ApplicantContext.xml,classpath:spring-security.xml</param-value> </context-param> <!--監(jiān)聽器--> <listener> <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class> </listener> <!--默認(rèn)過濾器--> <filter> <filter-name>springSecurityFilterChain</filter-name> <filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class> </filter> <filter-mapping> <filter-name>springSecurityFilterChain</filter-name> <url-pattern>/*</url-pattern> </filter-mapping> <!--spring-mvc中央處理器--> <servlet> <servlet-name>DispatcherServlet</servlet-name> <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class> <init-param> <param-name>contextConfigLocation</param-name> <param-value>classpath:spring-mvc.xml</param-value> </init-param> <load-on-startup>1</load-on-startup> </servlet> <servlet-mapping> <servlet-name>DispatcherServlet</servlet-name> <url-pattern>/</url-pattern> </servlet-mapping> <!--字符編碼轉(zhuǎn)換器--> <filter> <filter-name>CharacterEncodingFilter</filter-name> <filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class> <init-param> <param-name>encoding</param-name> <param-value>UTF-8</param-value> </init-param> </filter> <filter-mapping> <filter-name>CharacterEncodingFilter</filter-name> <url-pattern>/*</url-pattern> </filter-mapping> </web-app>
3.自定義用戶角色驗(yàn)證
package ssm.service; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.security.core.GrantedAuthority; import org.springframework.security.core.authority.AuthorityUtils; import org.springframework.security.core.authority.SimpleGrantedAuthority; import org.springframework.security.core.userdetails.User; import org.springframework.security.core.userdetails.UserDetails; import org.springframework.security.core.userdetails.UserDetailsService; import org.springframework.security.core.userdetails.UsernameNotFoundException; import org.springframework.stereotype.Service; import ssm.bean.Role; import ssm.bean.UserInfo; import ssm.dao.LoginDao; import java.util.ArrayList; import java.util.List; @Service("userinfo") public class UserinfoService implements IUserInfoService{ @Autowired LoginDao loginDao; @Override public UserDetails loadUserByUsername(String s) throws UsernameNotFoundException { //將s傳參從數(shù)據(jù)庫查詢是否用這個(gè)用戶 UserInfo info=loginDao.findByList(s); List<Role> list=info.getRoles(); List<GrantedAuthority> role= new ArrayList<GrantedAuthority>(); for(Role i:list){ role.add(new SimpleGrantedAuthority("ROLE_"+i.getRolename())); } System.out.println(s); return new User(info.getUsername(), "{noop}"+info.getPassword(),info.getStatus()!=0?true:false,true,true,true, role); } }
4.seculity自定義過濾器
package filter; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.core.annotation.Order; import org.springframework.security.access.SecurityMetadataSource; import org.springframework.security.access.intercept.AbstractSecurityInterceptor; import org.springframework.security.access.intercept.InterceptorStatusToken; import org.springframework.security.web.FilterInvocation; import org.springframework.security.web.access.intercept.FilterInvocationSecurityMetadataSource; import org.springframework.stereotype.Component; import org.springframework.stereotype.Service; import javax.servlet.*; import java.io.IOException; @Service("myFilter") public class MyFilter extends AbstractSecurityInterceptor implements Filter { @Autowired private FilterInvocationSecurityMetadataSource securityMetadataSource; @Override public Class<?> getSecureObjectClass() { return FilterInvocation.class; } @Override public SecurityMetadataSource obtainSecurityMetadataSource() { return securityMetadataSource; } @Autowired public void setMyAccessDecisionManager(MyAccessDescisionManager myAccessDescisionManager) { super.setAccessDecisionManager(myAccessDescisionManager); } @Override public void init(FilterConfig filterConfig) throws ServletException { } @Override public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { System.out.println("------------MyFilterSecurityInterceptor.doFilter()-----------開始攔截器了...."); FilterInvocation fi = new FilterInvocation(request, response, chain); InterceptorStatusToken token = super.beforeInvocation(fi); try { fi.getChain().doFilter(fi.getRequest(), fi.getResponse()); } catch (Exception e) { e.printStackTrace(); } finally { super.afterInvocation(token, null); } System.out.println("------------MyFilterSecurityInterceptor.doFilter()-----------攔截器該方法結(jié)束了...."); } @Override public void destroy() { } }
5.自定義用戶權(quán)限驗(yàn)證
package filter; import org.springframework.security.access.AccessDecisionManager; import org.springframework.security.access.AccessDeniedException; import org.springframework.security.access.ConfigAttribute; import org.springframework.security.authentication.InsufficientAuthenticationException; import org.springframework.security.core.Authentication; import org.springframework.security.core.GrantedAuthority; import org.springframework.stereotype.Component; import org.springframework.stereotype.Service; import java.util.Collection; import java.util.Iterator; @Service public class MyAccessDescisionManager implements AccessDecisionManager { @Override public void decide(Authentication authentication, Object object, Collection<ConfigAttribute> configAttributes)throws AccessDeniedException, InsufficientAuthenticationException { // TODO Auto-generated method stub System.out.println("MyAccessDescisionManager.decide()------------------驗(yàn)證用戶是否具有一定的權(quán)限--------"); if(configAttributes==null) return; Iterator<ConfigAttribute> it = configAttributes.iterator(); while(it.hasNext()){ String needResource = it.next().getAttribute(); //authentication.getAuthorities() 用戶所有的權(quán)限 for(GrantedAuthority ga:authentication.getAuthorities()){ System.out.println("ROLE_"+needResource); System.out.println(ga.getAuthority()); if(("ROLE_"+needResource).equals(ga.getAuthority())){ return; } } } throw new AccessDeniedException("--------MyAccessDescisionManager:decide-------權(quán)限認(rèn)證失敗!"); } @Override public boolean supports(ConfigAttribute attribute) { // TODO Auto-generated method stub return true; } @Override public boolean supports(Class<?> clazz) { // TODO Auto-generated method stub return true; } }
6.自定義初始化用戶角色和權(quán)限屬性
package filter; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.security.access.ConfigAttribute; import org.springframework.security.access.SecurityConfig; import org.springframework.security.web.FilterInvocation; import org.springframework.security.web.access.intercept.FilterInvocationSecurityMetadataSource; import org.springframework.stereotype.Component; import org.springframework.stereotype.Service; import org.springframework.util.AntPathMatcher; import ssm.bean.Premission; import ssm.bean.Role; import ssm.dao.LoginDao; import ssm.dao.MapperRoleDao; import ssm.dao.MapperUserDao; import java.util.*; @Service public class MySecurityMetadataSource implements FilterInvocationSecurityMetadataSource { /*@Autowired private IUserDao userDao; */ @Autowired private LoginDao loginDao; /* 保存資源和權(quán)限的對(duì)應(yīng)關(guān)系 key-資源url value-權(quán)限 */ private static Map<String, Collection<ConfigAttribute>> resourceMap = null; private AntPathMatcher urlMatcher = new AntPathMatcher(); public MySecurityMetadataSource() { //loadResourcesDefine(); } @Override public Collection<ConfigAttribute> getAllConfigAttributes() { return null; } private void loadResourcesDefine(){ resourceMap = new HashMap<String,Collection<ConfigAttribute>>(); System.out.println("MySecurityMetadataSource.loadResourcesDefine()--------------開始加載資源列表數(shù)據(jù)--------"); List<Role> roles; try { roles = loginDao.findByROleList(); for(Role role : roles){ List<Premission> permissions = role.getPremission(); for(Premission permission : permissions){ Collection<ConfigAttribute> configAttributes = null; ConfigAttribute configAttribute = new SecurityConfig(role.getRolename()); if(resourceMap.containsKey(permission.getUrl())){ configAttributes = resourceMap.get(permission.getUrl()); configAttributes.add(configAttribute); }else{ configAttributes = new ArrayList<ConfigAttribute>() ; configAttributes.add(configAttribute); resourceMap.put(permission.getUrl(), configAttributes); } } } System.out.println("11"); Set<String> set = resourceMap.keySet(); Iterator<String> it = set.iterator(); int i=0; while(it.hasNext()){ String s = it.next(); System.out.println(++i+"key:"+s+"|value:"+resourceMap.get(s)); } } catch (Exception e) { // TODO Auto-generated catch block e.printStackTrace(); } } /* * 根據(jù)請(qǐng)求的資源地址,獲取它所擁有的權(quán)限 */ @Override public Collection<ConfigAttribute> getAttributes(Object obj) throws IllegalArgumentException { if(null==resourceMap||resourceMap.size() == 0) { loadResourcesDefine(); } //獲取請(qǐng)求的url地址 String url = ((FilterInvocation)obj).getRequestUrl(); System.out.println("MySecurityMetadataSource:getAttributes()---------------請(qǐng)求地址為:"+url); Iterator<String> it = resourceMap.keySet().iterator(); while(it.hasNext()){ String _url = it.next(); if(url.indexOf("?")!=-1){ url = url.substring(0, url.indexOf("?")); } if(urlMatcher.match(_url,url)){ System.out.println("MySecurityMetadataSource:getAttributes()---------------需要的權(quán)限是:"+resourceMap.get(_url)); return resourceMap.get(_url); } } Collection<ConfigAttribute> nouse = new ArrayList<ConfigAttribute>(); nouse.add(new SecurityConfig("無相應(yīng)權(quán)限")); return nouse; } @Override public boolean supports(Class<?> arg0) { System.out.println("MySecurityMetadataSource.supports()---------------------"); return true; } }
到此這篇關(guān)于Spring-seculity權(quán)限使用的文章就介紹到這了,更多相關(guān)Spring-seculity權(quán)限使用內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
SpringBoot @RequestParam、@PathVaribale、@RequestBody實(shí)戰(zhàn)案例
這篇文章主要介紹了SpringBoot @RequestParam、@PathVaribale、@RequestBody實(shí)戰(zhàn)案例,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2020-11-11SpringBoot集成ActiveMQ的實(shí)戰(zhàn)全過程
消息隊(duì)列中間件是分布式系統(tǒng)中重要的組件,主要解決應(yīng)用耦合、異步消息、流量削鋒等問題,實(shí)現(xiàn)高性能、高可用、可伸縮和最終一致性架構(gòu),是大型分布式系統(tǒng)不可缺少的中間件,這篇文章主要給大家介紹了關(guān)于SpringBoot集成ActiveMQ的相關(guān)資料,需要的朋友可以參考下2021-11-11Java 中 String,StringBuffer 和 StringBuilder 的區(qū)別及用法
這篇文章主要介紹了Java 中 String,StringBuffer 和 StringBuilder 的區(qū)別及用法的相關(guān)資料,需要的朋友可以參考下2017-03-03Spring如何基于注解顯式實(shí)現(xiàn)自動(dòng)裝配
這篇文章主要介紹了Spring如何基于注解顯式實(shí)現(xiàn)自動(dòng)裝配,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2020-08-08淺談兩個(gè)jar包中包含完全相同的包名和類名的加載問題
下面小編就為大家?guī)硪黄獪\談兩個(gè)jar包中包含完全相同的包名和類名的加載問題。小編覺得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧2017-09-09Mabitis中的#與$符號(hào)區(qū)別及用法介紹
這篇文章主要介紹了Mabitis中的#與$符號(hào)區(qū)別,需要的朋友可以參考下2017-02-02