spring security 表單驗證流程

spring security是一款安全框架,其原理是驗證客戶端與服務端的數據是否一致,這個數據可以是令牌也可以是用戶名與密碼的組合,那麼其工作原理是什麼樣,帶着這樣的疑問,我使用debug模式進行了驗證;

首先導入包:

		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-security</artifactId>
		</dependency>
@RestController
public class HelloWorld {
	
	@RequestMapping("/Hello")
	public String HelloController() {
		return "Hello World!";
	}
}

訪問localhost:8080/Hello,發現出現login表單的驗證畫面(用戶user,密碼會顯示在控制檯),說明框架已經起作用了;

 

查詢資料,spring security核心組件有:SecurityContext、SecurityContextHolder、Authentication、Userdetails 和 AuthenticationManager。

Authentication主要存放的是前端表單輸入的信息;

Userdetails 是一個接口,存放的是從數據庫裏面取出的角色數據,需要實現getAuthorities()方法;

UserDetailsService也是一個接口,存放的是從數據庫裏面取出的數據(用戶名,密碼,角色),需要實現loadUserByUsername(String username)方法;

現在前後端的數據全部有了,其驗證的程序在哪?我們沒有寫驗證程序卻可以進行表單驗證,spring security默認缺省的驗證程序是org.springframework.security.authentication.ProviderManager(AuthenticationManager的實現類):

private List<AuthenticationProvider> providers = Collections.emptyList();

<AuthenticationProvider>默認的實例化對象是:DaoAuthenticationProvider,可以看到該代碼裏面有如下內容:

	@SuppressWarnings("deprecation")
	protected void additionalAuthenticationChecks(UserDetails userDetails,
			UsernamePasswordAuthenticationToken authentication)
			throws AuthenticationException {
		if (authentication.getCredentials() == null) {
			logger.debug("Authentication failed: no credentials provided");

			throw new BadCredentialsException(messages.getMessage(
					"AbstractUserDetailsAuthenticationProvider.badCredentials",
					"Bad credentials"));
		}

		String presentedPassword = authentication.getCredentials().toString();

		if (!passwordEncoder.matches(presentedPassword, userDetails.getPassword())) {
			logger.debug("Authentication failed: password does not match stored value");

			throw new BadCredentialsException(messages.getMessage(
					"AbstractUserDetailsAuthenticationProvider.badCredentials",
					"Bad credentials"));
		}
	}

if (authentication.getCredentials() == null) { :這裏驗證用戶名是否爲空;

if (!passwordEncoder.matches(presentedPassword, userDetails.getPassword())) { : 這裏驗證密碼,presentedPassword是前端傳進來的密碼,userDetails.getPassword()是數據庫中傳進來的密碼(已經加密過,其加密方式需要與passwordEncoder加密飯方式相同);

簡單的驗證就這樣完成了;

出現的問題:

1、驗證完成後,報403錯誤,這個錯誤查詢下來是權限不足,在SecurityConfig(extends WebSecurityConfigurerAdapter)裏面設置了http.authorizeRequests().antMatchers("/**").hasRole("ADMIN");在getAuthorities()(UserDetails的實現類)方法裏面也設置了 collection.add(new SimpleGrantedAuthority(role));

解決辦法是:將new SimpleGrantedAuthority(role)改爲:new SimpleGrantedAuthority("ROLE_"+role),這是這個框架的規則;

 

 

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章