SpringBoot實戰電商項目mall(20k+star)地址: https://github.com/macrozheng/mall
Spring Cloud Security 爲構建安全的SpringBoot應用提供了一系列解決方案,結合Oauth2能夠實現單點登陸功能,本文將對其單點登陸用法進行詳細介紹。java
單點登陸(Single Sign On)指的是當有多個系統須要登陸時,用戶只需登陸一個系統,就能夠訪問其餘須要登陸的系統而無需登陸。git
這裏咱們建立一個oauth2-client服務做爲須要登陸的客戶端服務,使用上一節中的oauth2-jwt-server服務做爲認證服務,當咱們在oauth2-jwt-server服務上登陸之後,就能夠直接訪問oauth2-client須要登陸的接口,來演示下單點登陸功能。
<dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-oauth2</artifactId> </dependency> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-security</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>io.jsonwebtoken</groupId> <artifactId>jjwt</artifactId> <version>0.9.0</version> </dependency>
server: port: 9501 servlet: session: cookie: name: OAUTH2-CLIENT-SESSIONID #防止Cookie衝突,衝突會致使登陸驗證不經過 oauth2-server-url: http://localhost:9401 spring: application: name: oauth2-client security: oauth2: #與oauth2-server對應的配置 client: client-id: admin client-secret: admin123456 user-authorization-uri: ${oauth2-server-url}/oauth/authorize access-token-uri: ${oauth2-server-url}/oauth/token resource: jwt: key-uri: ${oauth2-server-url}/oauth/token_key
@EnableOAuth2Sso @SpringBootApplication public class Oauth2ClientApplication { public static void main(String[] args) { SpringApplication.run(Oauth2ClientApplication.class, args); } }
/** * Created by macro on 2019/9/30. */ @RestController @RequestMapping("/user") public class UserController { @GetMapping("/getCurrentUser") public Object getCurrentUser(Authentication authentication) { return authentication; } }
修改oauth2-jwt-server模塊中的AuthorizationServerConfig類,將綁定的跳轉路徑爲http://localhost:9501/login,並添加獲取祕鑰時的身份認證。github
/** * 認證服務器配置 * Created by macro on 2019/9/30. */ @Configuration @EnableAuthorizationServer public class AuthorizationServerConfig extends AuthorizationServerConfigurerAdapter { //以上省略一堆代碼... @Override public void configure(ClientDetailsServiceConfigurer clients) throws Exception { clients.inMemory() .withClient("admin") .secret(passwordEncoder.encode("admin123456")) .accessTokenValiditySeconds(3600) .refreshTokenValiditySeconds(864000) // .redirectUris("http://www.baidu.com") .redirectUris("http://localhost:9501/login") //單點登陸時配置 .scopes("all") .authorizedGrantTypes("authorization_code","password","refresh_token"); } @Override public void configure(AuthorizationServerSecurityConfigurer security) { security.tokenKeyAccess("isAuthenticated()"); // 獲取密鑰須要身份認證,使用單點登陸時必須配置 } }
autoApprove(true)
配置:/** * 認證服務器配置 * Created by macro on 2019/9/30. */ @Configuration @EnableAuthorizationServer public class AuthorizationServerConfig extends AuthorizationServerConfigurerAdapter { //以上省略一堆代碼... @Override public void configure(ClientDetailsServiceConfigurer clients) throws Exception { clients.inMemory() .withClient("admin") .secret(passwordEncoder.encode("admin123456")) .accessTokenValiditySeconds(3600) .refreshTokenValiditySeconds(864000) // .redirectUris("http://www.baidu.com") .redirectUris("http://localhost:9501/login") //單點登陸時配置 .autoApprove(true) //自動受權配置 .scopes("all") .authorizedGrantTypes("authorization_code","password","refresh_token"); } }
這裏咱們使用Postman來演示下如何使用正確的方式調用須要登陸的客戶端接口。
{ "authorities": [ { "authority": "admin" } ], "details": { "remoteAddress": "0:0:0:0:0:0:0:1", "sessionId": "63BB793E35383B2FFC608333B3BF4988", "tokenValue": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VyX25hbWUiOiJtYWNybyIsInNjb3BlIjpbImFsbCJdLCJleHAiOjE1NzI2OTAxNzUsImF1dGhvcml0aWVzIjpbImFkbWluIl0sImp0aSI6IjIwN2U5MTQzLTVjNTUtNDhkMS1iZmU3LTgwMzUyZTQ3Y2QyZCIsImNsaWVudF9pZCI6ImFkbWluIiwiZW5oYW5jZSI6ImVuaGFuY2UgaW5mbyJ9.xf3cBu9yCm0sME0j3UcP53FwF4tJVJC5aJbEj_Y2XcU", "tokenType": "bearer", "decodedDetails": null }, "authenticated": true, "userAuthentication": { "authorities": [ { "authority": "admin" } ], "details": null, "authenticated": true, "principal": "macro", "credentials": "N/A", "name": "macro" }, "clientOnly": false, "oauth2Request": { "clientId": "admin", "scope": [ "all" ], "requestParameters": { "client_id": "admin" }, "resourceIds": [], "authorities": [], "approved": true, "refresh": false, "redirectUri": null, "responseTypes": [], "extensions": {}, "grantType": null, "refreshTokenRequest": null }, "principal": "macro", "credentials": "", "name": "macro" }
/** * 在接口上配置權限時使用 * Created by macro on 2019/10/11. */ @Configuration @EnableGlobalMethodSecurity(prePostEnabled = true) @Order(101) public class SecurityConfig extends WebSecurityConfigurerAdapter { }
/** * Created by macro on 2019/9/30. */ @RestController @RequestMapping("/user") public class UserController { @PreAuthorize("hasAuthority('admin')") @GetMapping("/auth/admin") public Object adminAuth() { return "Has admin auth!"; } }
admin
權限的賬號,好比andy:123456
獲取令牌後訪問該接口,會發現沒有權限訪問。
springcloud-learning ├── oauth2-jwt-server -- 使用jwt的oauth2認證測試服務 └── oauth2-client -- 單點登陸的oauth2客戶端服務
https://github.com/macrozheng/springcloud-learningweb
mall項目全套學習教程連載中,關注公衆號第一時間獲取。spring