Spring security權(quán)限配置與使用大全
簡介
Spring Security 是為了基于Spring的應(yīng)用程序提供的聲明式安全保護(hù)的安全性框架。Spring Security 提供了完整的安全性解決方案,它能夠在Web請求級別和方法調(diào)用級別處理身份認(rèn)證和授權(quán)。因為基于Spring框架,所以SPring Security充分使用了一覽注入和面向切面技術(shù)。
Spring Security 本質(zhì)上是借助一系列的 Servlet Filter來提供各種安全性功能,但這并不需要我們手動去添加或者創(chuàng)建多個Filter。實際上,我們僅需要配置一個Filter即可。
DelegatingFilterProxy 是一個特殊的Filter,他本身并沒有做太多工作,而是將工作委托給了一個注入到Spring應(yīng)用上下文的Filter實現(xiàn)類。

在本例中,主要講解spring-security的配置與使用,實現(xiàn)方式為:
1.將用戶、權(quán)限、資源(url)采用數(shù)據(jù)庫存儲
2.自定義過濾器,代替原有的 FilterSecurityInterceptor
3.自定義實現(xiàn) UserDetailsService、Filter、AccessDecisionManager和FilterInvocationSecurityMetadataSource并在配置文件進(jìn)行相應(yīng)的配置
4.Spring-seculity在自定義用戶驗證的類加載必須早于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" />-->
<!--用戶賬戶和密碼表單驗證-->
<!--login-page="攔截跳轉(zhuǎn)頁面" login-processing-url="用戶登陸驗證路徑"
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"/>
<!--禁止跨域請求-->
<security:csrf disabled="true"/>
</security:http>
<bean id="myFilter" class="filter.MyFilter"/>
<bean id="userinfo" class="ssm.service.UserinfoService"/>
<!--固定用戶賬戶和密碼的驗證-->
<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.自定義用戶角色驗證
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ù)庫查詢是否用這個用戶
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)限驗證
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()------------------驗證用戶是否具有一定的權(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)限的對應(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ù)請求的資源地址,獲取它所擁有的權(quán)限
*/
@Override
public Collection<ConfigAttribute> getAttributes(Object obj)
throws IllegalArgumentException {
if(null==resourceMap||resourceMap.size() == 0) {
loadResourcesDefine();
}
//獲取請求的url地址
String url = ((FilterInvocation)obj).getRequestUrl();
System.out.println("MySecurityMetadataSource:getAttributes()---------------請求地址為:"+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)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Java泛型extends關(guān)鍵字設(shè)置邊界的實現(xiàn)
這篇文章主要介紹了Java泛型extends關(guān)鍵字設(shè)置邊界的實現(xiàn),文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2019-09-09
SpringBoot實現(xiàn)MD5加鹽算法的示例代碼
加鹽算法是一種用于增強密碼安全性的技術(shù),本文主要介紹了SpringBoot實現(xiàn)MD5加鹽算法的示例代碼,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2025-03-03
Java List的remove()方法陷阱以及性能優(yōu)化
Java List在進(jìn)行remove()方法是通常容易踩坑,本文就詳細(xì)的介紹一下陷阱以及性能優(yōu)化,感興趣的可以了解一下2021-10-10
java注解處理器學(xué)習(xí)在編譯期修改語法樹教程
這篇文章主要為大家介紹了java注解處理器學(xué)習(xí)在編譯期修改語法樹教程,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2022-09-09

