本文記錄一下使用SpringSecurityOAuth2實現授權的步驟。
1、相關知識
OAuth協議簡介:https://www.cnblogs.com/javasl/p/13054133.html
OAuth 2.0官網:https://oauth.net/2/
2、構建項目
本文使用的springboot版本是2.0.4.RELEASE,不同版本可能會有所區別。下面是主要的配置文件和類:
1)pom依賴
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-security</artifactId> </dependency> <dependency> <groupId>org.springframework.security.oauth.boot</groupId> <artifactId>spring-security-oauth2-autoconfigure</artifactId> <version>2.1.3.RELEASE</version> </dependency>
2)application.properties
security.oauth2.client.client-id = MyProject security.oauth2.client.client-secret = MyProject_123 security.oauth2.client.registered-redirect-uri = www.baidu.com
指定應用的ID和秘鑰,redirect-uri暫時沒用到,但必須有,否則無法演示授權效果。
3)主配置類
@EnableWebSecurity @Configuration public class WebSecurityConfig extends WebSecurityConfigurerAdapter{ @Override protected void configure(HttpSecurity http) throws Exception { http.httpBasic().and().csrf().disable(); } @Bean public PasswordEncoder passwordEncoder() { return new BCryptPasswordEncoder(); } }
4)用戶認證類
@Component public class MyUserDetailsService implements UserDetailsService{ @Autowired private PasswordEncoder passwordEncoder; @Override public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException { System.out.println("登錄用戶名:"+username); String password = passwordEncoder.encode("123456"); return new User(username,password,true,true,true,true, AuthorityUtils.commaSeparatedStringToAuthorityList("admin,ROLE_USER")); } }
5)認證服務器類
@Configuration @EnableAuthorizationServer public class AuthorizationServerConfig { }
6)啟動類
@SpringBootApplication public class App { public static void main(String[] args) { SpringApplication.run(App.class, args); } }
3、OAuth 2.0協議相關參數講解
登錄官網 訪問:https://tools.ietf.org/html/rfc6749,里面第4章詳解介紹了4種授權模式。
1)授權碼模式下,請求授權碼所需參數:
response_type:------必填,值是固定的常量code
client_id:-------------必填,值是應用ID,配置文件中定義的MyProject
redirect_uri:---------非必填,值是回調地址
scope:----------------非必填,值是范圍
state:-----------------非必填,值是狀態
2)授權碼模式下,請求Token所需參數:
grant_type:---------必填,值是固定的常量authorization_code
code:----------------必填,值是上面一步請求返回的授權碼
redirect_uri:--------必填,值是回調地址
client_id:------------必填,值是應用ID,配置文件中定義的MyProject
3)密碼模式下,請求Token所需參數:
grant_type:---------必填,值是固定的常量password
username:----------必填,值是用戶名
password:-----------必填,值是用戶密碼
scope:---------------非必填,范圍
4、演示OAuth2授權
啟動項目,使用Restlet Client-REST API Testing插件測試
1)測試授權碼模式
瀏覽器輸入:http://localhost:8080/oauth/authorize?response_type=code&client_id=MyProject&scope=all
彈出認證頁面,輸入用戶名密碼,用戶名隨意,密碼是123456,參考MyUserDetailsService.java。
認證成功后,跳轉到授權頁面。
選擇同意授權,跳轉到配置的回調url,瀏覽器中顯示:https://www.baidu.com/?code=Q52K1I。其中Q52K1I就是獲取的授權碼。
使用插件發送POST請求,獲取Token
2)測試密碼模式
說明:
1)可以看到兩種方式獲取的Token是一樣的,因為同一個用戶在系統中已經存在Token了,就不會再創建,直接返回。
2)HEADERS第一個參數Authorization,點擊Add authorization創建,彈出如下框,用戶名、密碼分別是應用的ID和秘鑰。
3)HEADERS第二個參數Content-Type,值為application/x-www-form-urlencoded,創建body參數時自動生成的。
5、演示獲取資源
1)新增資源服務類
@Configuration @EnableResourceServer public class ResourceServerConfig { }
2)新增測試類
@RestController public class UserController { @GetMapping("/currentUser") public Object getCurrentUser(@AuthenticationPrincipal UserDetails user) { return user; } }
3)啟動服務,用密碼模式獲取Token,如上。
4)訪問資源,獲取當前用戶信息
注意:參數名是Authorization,參數值是bearer e9c07170-fb16-4c20-a4cb-71fd623ccffb(token_type + access_token)