SpringBoot實戰電商項目mall(20k+star)地址:github.com/macrozheng/…java
Spring Cloud Security 爲構建安全的SpringBoot應用提供了一系列解決方案,結合Oauth2能夠實現單點登陸功能,本文將對其單點登陸用法進行詳細介紹。git
單點登陸(Single Sign On)指的是當有多個系統須要登陸時,用戶只需登陸一個系統,就能夠訪問其餘須要登陸的系統而無需登陸。github
這裏咱們建立一個oauth2-client服務做爲須要登陸的客戶端服務,使用上一節中的oauth2-jwt-server服務做爲認證服務,當咱們在oauth2-jwt-server服務上登陸之後,就能夠直接訪問oauth2-client須要登陸的接口,來演示下單點登陸功能。web
<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,並添加獲取祕鑰時的身份認證。spring
/** * 認證服務器配置 * 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()"); // 獲取密鑰須要身份認證,使用單點登陸時必須配置
}
}
複製代碼
啓動oauth2-client服務和oauth2-jwt-server服務;json
訪問客戶端須要受權的接口http://localhost:9501/user/getCurrentUser會跳轉到受權服務的登陸界面;安全
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來演示下如何使用正確的方式調用須要登陸的客戶端接口。服務器
訪問客戶端須要登陸的接口:http://localhost:9501/user/getCurrentUsercookie
使用Oauth2認證方式獲取訪問令牌:session
{
"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客戶端服務
複製代碼
mall項目全套學習教程連載中,關注公衆號第一時間獲取。