先解釋一下Oauth2 是什麼?
OAuth2 是一個授權代理服務,是一種開放授權協議、其核心就是第三方應用頒發令牌
OAuth2有4種角色
分別爲資源擁有者、資源服務、授權服務、客戶端第三方應用
OAuth2有4種授權方式,分別爲
- 授權碼(authorization-code)
- 簡化模式(implicit)
- 密碼式(password):
- 客戶端憑證(client credentials)
下面開始是整合Oauth2之授權碼案例
創建一個Sprng boot 項目,具體的項目工程結構如下
主要的POM文件內容如下:
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
<!-- OAuth 2.0 的核心jar -->
<dependency>
<groupId>org.springframework.security.oauth</groupId>
<artifactId>spring-security-oauth2</artifactId>
<version>2.3.7.RELEASE</version>
</dependency>
</dependencies>
spring-security-oauth2主要一些如下
AuthorizationEndpoint、TokenEndpoint、CheckTokenEndpoint、AuthorizationServerEndpointsConfiguration
授權服務的配置如下:
/**
* 授權服務器相關的配置
*/
@Configuration
@EnableAuthorizationServer
public class GrantServerConfig extends AuthorizationServerConfigurerAdapter {
@Override
public void configure(ClientDetailsServiceConfigurer clients)
throws Exception {
clients.inMemory()
.withClient("cloud_grant")
.secret("cloud_grant")
.redirectUris("http://127.0.0.1:8001/login")
// 授權碼模式
.authorizedGrantTypes("authorization_code")
.scopes("res_list", "res_info");
}
}
資源服務的配置如下:
/**
* 配置資源服務器的相關的配置,進行授權
*/
@Configuration
@EnableResourceServer
//@Order(Integer.MAX_VALUE)
public class ResourceServerConfig extends ResourceServerConfigurerAdapter {
@Override
public void configure(HttpSecurity http) throws Exception {
http.authorizeRequests()
.anyRequest()
.authenticated()
.and()
.requestMatchers()
.antMatchers("/api/**");
}
}
受保存的資源服務列表代碼如下:
@RestController
@RequestMapping("/api/res")
public class ResourceController {
@GetMapping
public Res getRes(){
Res res=new Res();
res.setId(1);
res.setResCode("home_list");
res.setResName("主頁列表");
return res;
}
}
啓動應用,獲取授權碼
輸入如下的請求地址
http://127.0.0.1:8080/oauth/authorize?client_id=cloud_grant&redirect_uri=http://127.0.0.1:8001/login&response_type=code&scope=res_info
出現如下問題:
User must be authenticated with Spring Security before authorization can be completed.
解決辦法
加入如下的配置
@EnableWebSecurity
@EnableGlobalMethodSecurity(prePostEnabled = true)
public class SecurityConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
http.csrf().disable();
http.requestMatchers()
.antMatchers("/oauth/**","/login/**","/logout/**")
.and()
.authorizeRequests()
.antMatchers("/oauth/**").authenticated()
.and()
.formLogin().permitAll(); //新增login form支持用戶登錄及授權
}
}
再輸入如下的請求地址
http://127.0.0.1:8080/oauth/authorize?client_id=cloud_grant&redirect_uri=http://127.0.0.1:8001/login&response_type=code&scope=res_info
輸入安全用戶名和密碼:
這是因爲密碼加密配置器沒有找到的原因,增加一個密碼配置器就可以了
@Bean
public PasswordEncoder passwordEncoder(){
return new BCryptPasswordEncoder();
}
但是又出現下面這個問題
通過打印日誌可知
2019-12-28 20:33:45.298 INFO 5904 --- [nio-8080-exec-1] o.s.web.servlet.DispatcherServlet : Completed initialization in 7 ms
2019-12-28 20:33:45.429 WARN 5904 --- [nio-8080-exec-1] o.s.s.c.bcrypt.BCryptPasswordEncoder : Encoded password does not look like BCrypt
2019-12-28 20:34:11.250 WARN 5904 --- [nio-8080-exec-4] o.s.s.c.bcrypt.BCryptPasswordEncoder : Encoded password does not look like BCrypt
2019-12-28 20:34:21.744 WARN 5904 --- [nio-8080-exec-7] o.s.s.c.bcrypt.BCryptPasswordEncoder : Encoded password does not look like BCrypt
2019-12-28 20:34:40.954 WARN 5904 --- [io-8080-exec-10] o.s.s.c.bcrypt.BCryptPasswordEncoder : Encoded password does not look like BCrypt
定位到相關的源代碼可知,密碼的規則的長度和複雜度不夠
解析辦法如下
public static void main(String[] args) {
String result=new BCryptPasswordEncoder().encode("yang123456");
System.out.println("result = [" + result + "]");//$2a$10$6kzPmiwy3mp4J8gbY7ooleQiCik5llTxhjQXpNJkilsGMJOs7o0hC
}
修改application.yml的密碼替換成上面程序得到的經過BCryptPasswordEncoder編碼之後密碼,也就是
spring:
security:
user:
name: yangyang
password: $2a$10$6kzPmiwy3mp4J8gbY7ooleQiCik5llTxhjQXpNJkilsGMJOs7o0hC
帶着token訪問受訪問的資源,出現如下所示,則表示成功
執行成功,後面再補充其他的授權模式