您好,登錄后才能下訂單哦!
之前的兩篇文章,講述了Spring Security 結(jié)合 OAuth3 、JWT 的使用,這一節(jié)要求對 OAuth3、JWT 有了解,若不清楚,先移步到下面兩篇提前了解下。
Spring Boot Security 整合 OAuth3 設(shè)計(jì)安全API接口服務(wù)
Spring Boot Security 整合 JWT 實(shí)現(xiàn) 無狀態(tài)的分布式API接口
這一篇我們來實(shí)現(xiàn) 支持 JWT令牌 的授權(quán)服務(wù)器。
使用 OAuth3 是向認(rèn)證服務(wù)器申請令牌,客戶端拿這令牌訪問資源服務(wù)服務(wù)器,資源服務(wù)器校驗(yàn)了令牌無誤后,如果資源的訪問用到用戶的相關(guān)信息,那么資源服務(wù)器還需要根據(jù)令牌關(guān)聯(lián)查詢用戶的信息。
使用 JWT 是客戶端通過用戶名、密碼 請求服務(wù)器獲取 JWT,服務(wù)器判斷用戶名和密碼無誤之后,可以將用戶信息和權(quán)限信息經(jīng)過加密成 JWT 的形式返回給客戶端。在之后的請求中,客戶端攜帶 JWT 請求需要訪問的資源,如果資源的訪問用到用戶的相關(guān)信息,那么就直接從JWT中獲取到。
所以,如果我們在使用 OAuth3 時(shí)結(jié)合JWT ,就能節(jié)省集中式令牌校驗(yàn)開銷,實(shí)現(xiàn)無狀態(tài)授權(quán)認(rèn)證。
工程名 | 端口 | 作用 |
---|---|---|
jwt-authserver | 8080 | 授權(quán)服務(wù)器 |
jwt-resourceserver | 8081 | 資源服務(wù)器 |
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-oauth3-resource-server</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-oauth3-client</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.security.oauth.boot</groupId>
<artifactId>spring-security-oauth3-autoconfigure</artifactId>
<version>2.1.3.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-jwt</artifactId>
<version>1.0.10.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
@Configuration
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
http.
authorizeRequests().antMatchers("/**").permitAll();
}
@Autowired
public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
auth
.inMemoryAuthentication()
.withUser("user").password("123456").roles("USER");
}
@Bean
@Override
public AuthenticationManager authenticationManagerBean() throws Exception {
return super.authenticationManagerBean();
}
@Bean
public PasswordEncoder passwordEncoder() {
return new PasswordEncoder() {
@Override
public String encode(CharSequence charSequence) {
return charSequence.toString();
}
@Override
public boolean matches(CharSequence charSequence, String s) {
return Objects.equals(charSequence.toString(),s);
}
};
}
}
為了方便,使用內(nèi)存模式,在內(nèi)存中創(chuàng)建一個(gè)用戶 user 密碼 123456。
/**
* 授權(quán)服務(wù)器
*/
@Configuration
@EnableAuthorizationServer
public class OAuth3AuthorizationServer extends AuthorizationServerConfigurerAdapter {
/**
* 注入AuthenticationManager ,密碼模式用到
*/
@Autowired
private AuthenticationManager authenticationManager;
/**
* 對Jwt簽名時(shí),增加一個(gè)密鑰
* JwtAccessTokenConverter:對Jwt來進(jìn)行編碼以及解碼的類
*/
@Bean
public JwtAccessTokenConverter accessTokenConverter() {
JwtAccessTokenConverter converter = new JwtAccessTokenConverter();
converter.setSigningKey("test-secret");
return converter;
}
/**
* 設(shè)置token 由Jwt產(chǎn)生,不使用默認(rèn)的透明令牌
*/
@Bean
public JwtTokenStore jwtTokenStore() {
return new JwtTokenStore(accessTokenConverter());
}
@Override
public void configure(AuthorizationServerEndpointsConfigurer endpoints) throws Exception {
endpoints
.authenticationManager(authenticationManager)
.tokenStore(jwtTokenStore())
.accessTokenConverter(accessTokenConverter());
}
@Override
public void configure(ClientDetailsServiceConfigurer clients) throws Exception {
clients.inMemory()
.withClient("clientapp")
.secret("123")
.scopes("read")
//設(shè)置支持[密碼模式、授權(quán)碼模式、token刷新]
.authorizedGrantTypes(
"password",
"authorization_code",
"refresh_token");
}
}
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-oauth3-resource-server</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-oauth3-client</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.security.oauth.boot</groupId>
<artifactId>spring-security-oauth3-autoconfigure</artifactId>
<version>2.1.3.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-jwt</artifactId>
<version>1.0.10.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
@RestController("/api")
public class HelloController {
@PostMapping("/api/hi")
public String say(String name) {
return "hi , " + name;
}
}
/**
* 資源服務(wù)器
*/
@Configuration
@EnableResourceServer
public class OAuth3ResourceServer extends ResourceServerConfigurerAdapter {
@Override
public void configure(HttpSecurity http) throws Exception {
http
.authorizeRequests()
.anyRequest().authenticated().and()
.requestMatchers().antMatchers("/api/**");
}
}
server:
port: 8081
security:
oauth3:
resource:
jwt:
key-value: test-secret
參數(shù)說明:
請求令牌
curl -X POST --user 'clientapp:123' -d 'grant_type=password&username=user&password=123456' http://localhost:8080/oauth/token
返回JWT令牌
{
"access_token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJleHAiOjE1NTQ0MzExMDgsInVzZXJfbmFtZSI6InVzZXIiLCJhdXRob3JpdGllcyI6WyJST0xFX1VTRVIiXSwianRpIjoiOGM0YWMyOTYtMDQwYS00Y2UzLTg5MTAtMWJmNjZkYTQwOTk3IiwiY2xpZW50X2lkIjoiY2xpZW50YXBwIiwic2NvcGUiOlsicmVhZCJdfQ.YAaSRN0iftmlR6Khz9UxNNEpHHn8zhZwlQrCUCPUmsU",
"token_type": "bearer",
"refresh_token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VyX25hbWUiOiJ1c2VyIiwic2NvcGUiOlsicmVhZCJdLCJhdGkiOiI4YzRhYzI5Ni0wNDBhLTRjZTMtODkxMC0xYmY2NmRhNDA5OTciLCJleHAiOjE1NTY5Nzk5MDgsImF1dGhvcml0aWVzIjpbIlJPTEVfVVNFUiJdLCJqdGkiOiI0ZjA5M2ZjYS04NmM0LTQxZWUtODcxZS1kZTY2ZjFhOTI0NTAiLCJjbGllbnRfaWQiOiJjbGllbnRhcHAifQ.vvAE2LcqggBv8pxuqU6RKPX65bl7Zl9dfcoIbIQBLf4",
"expires_in": 43199,
"scope": "read",
"jti": "8c4ac296-040a-4ce3-8910-1bf66da40997"
}
攜帶JWT令牌請求資源
curl -X POST -H "authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJleHAiOjE1NTQ0MzExMDgsInVzZXJfbmFtZSI6InVzZXIiLCJhdXRob3JpdGllcyI6WyJST0xFX1VTRVIiXSwianRpIjoiOGM0YWMyOTYtMDQwYS00Y2UzLTg5MTAtMWJmNjZkYTQwOTk3IiwiY2xpZW50X2lkIjoiY2xpZW50YXBwIiwic2NvcGUiOlsicmVhZCJdfQ.YAaSRN0iftmlR6Khz9UxNNEpHHn8zhZwlQrCUCPUmsU" -d 'name=zhangsan' http://localhost:8081/api/hi
返回
hi , zhangsan
https://github.com/gf-huanchupk/SpringBootLearning/tree/master/springboot-security-oauth3-jwt
歡迎關(guān)注我的公眾號(hào)《程序員果果》,關(guān)注有驚喜~~
免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。