[原創]SpringSecurity控制授權(鑒權)功能介紹


1.spring security 過濾器鏈

​ spring security中的除了用戶登錄校驗相關的過濾器,最后還包含了鑒權功能的過濾器,還有匿名資源訪問的過濾器鏈,相關的圖解如下:

2.控制授權的相關類

​ 這里是整個spring security的過濾器鏈中的授權流程中控制權限的類的相關圖示:

​ 這里主要是從AccessDecisionVoter的投票者(譯稱)把信息傳遞給投票管理者AccessDecisionManager,最終來判斷是過還是不過(也就是有沒有權限).有兩種可能的類:

​ 1.不管有多少請求投票不過,只要有一個過就可以通過(UnanimousBased);

​ 2.不管有多少請求投票通過,只要有一個不通過就不讓通過(AffirmativeBased);

​ 3.比較投通過和不通過的個數,誰多久就按照誰的方式來(Consensusbased).

​ 這里可以可能聽起來有點繞,但實際上就是三種控制權限的方式類,我們可以認為Spring security已經幫我們做好了最終的判斷,我們只需要當一個旁觀者即可.

​ 我們再來關注SecurityContextHolder這個類,他會將我們的權限信息封裝到Authentication中,SecurityConfig則是相關的Spring security的配置信息,這個類會將相關的信息傳遞到ConfigAttribute中.

3.配置簡單的權限

​ 這個在身份信息固定,並且不會經常變動的情況下可以按照如下配置,否則不建議這么做,這里只適用於簡單的場景.

MyUserDetailsService:

private SocialUserDetails buildUser(String userId) {
		// 根據用戶名查找用戶信息
		//根據查找到的用戶信息判斷用戶是否被凍結
		/**
		 * 可以從數據庫查出來用戶名和密碼進行比對,為了方便我這里就直接固定了
		 */
		String password = passwordEncoder.encode("123456");
		logger.info("數據庫密碼是:"+password);
		//注意這里配置角色的時候需要加ROLE_前綴
		return new SocialUser(userId, password,
				true, true, true, true,
				AuthorityUtils.commaSeparatedStringToAuthorityList("ROLE_ADMIN"));
	}

BrowserSecurityConfig:

//這里是硬編碼權限 只限於簡單的用戶權限 這里的角色名稱嚴格區分大小寫
   //這里可以指定HttpMethod  如HttpMethod.GET,
    .antMatchers("/user/**").hasRole("ADMIN")
        .anyRequest()     //所有請求
        .authenticated() //都需身份認證

4.權限表達式

​ 之前我們一直都有用到權限表達式,比如最常用的permitAll和Authenticated,這個權限表達式就是允許所有都能訪問的意思,其他的相關的權限表達式如下所示:

這里可以改寫權限的表達如下:

.antMatchers("/user/**").access("hasRole('ADMIN') and hasIpAddress('XXXXXX')")
        .anyRequest()     //所有請求
        .authenticated() //都需身份認證

5.spring security控制授權代碼封裝

![](https://img2018.cnblogs.com/blog/1373932/201905/1373932-20190504192151567-564940247.png)

代碼相關:

AuthorizeConfigProvider:

/**
 * 這個是授權的類
 */
public interface AuthorizeConfigProvider {

    void config(ExpressionUrlAuthorizationConfigurer<HttpSecurity>.ExpressionInterceptUrlRegistry config);
}

CityAuthorizeConfigProvider:

//配置permitAll的路徑
@Component
public class CityAuthorizeConfigProvider implements AuthorizeConfigProvider {
    @Autowired
    private SecurityProperties securityProperties;
    @Override
    public void config(ExpressionUrlAuthorizationConfigurer<HttpSecurity>.ExpressionInterceptUrlRegistry config) {
        config.antMatchers(
                "/static/**","/page/login","/page/failure","/page/mobilePage",
                "/code/image","/code/sms","/authentication/mobile",securityProperties.getBrower().getSignUPUrl(),
                "/user/register","/page/registerPage","/page/invalidSession","/page/logoutSuccess",securityProperties.getBrower().getSignOutUrl()

        )
                .permitAll();
    }
}

AuthorizeConfigManager:

/**
 * AuthorizeConfigManager
 */
public interface AuthorizeConfigManager {
    void config(ExpressionUrlAuthorizationConfigurer<HttpSecurity>.ExpressionInterceptUrlRegistry config);
}

CityAuthorizeConfigManager:

@Component
public class CityAuthorizeConfigManager implements AuthorizeConfigManager  {

    @Autowired
    private Set<AuthorizeConfigProvider> authorizeConfigProviders;

    @Override
    public void config(ExpressionUrlAuthorizationConfigurer<HttpSecurity>.ExpressionInterceptUrlRegistry config) {
        for (AuthorizeConfigProvider authorizeConfigProvider : authorizeConfigProviders) {
            authorizeConfigProvider.config(config);
        }
        //除了自己配置的CityAuthorizeConfigProvider的內容外 其他的都需要認證
        config.anyRequest().authenticated();
    }
}

在user中我們可以配置訪問的頁面權限:

DemoAuthorizeConifgProvider:

@Component
public class DemoAuthorizeConifgProvider implements AuthorizeConfigProvider {

    @Override
    public void config(ExpressionUrlAuthorizationConfigurer<HttpSecurity>.ExpressionInterceptUrlRegistry config) {

        config.antMatchers("/demo.html","/user/**")
                .hasRole("ADMIN");
    }
}

注意在BrowserSecurityConfig中注釋掉相關的代碼后需要加入如下代碼:

@Autowired
private AuthorizeConfigManager authorizeConfigManager;

在configure方法中調用:
authorizeConfigManager.config(http.authorizeRequests());

配置完后我們登陸進來,訪問http://localhost:8060/demo.html 顯示403權限拒絕,這個就說明權限生效了

4.項目git地址

(喜歡記得點星支持哦,謝謝!)

https://github.com/fengcharly/spring-security-oauth2.0


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM