文章目錄- 摘要
- 單點(diǎn)登錄簡(jiǎn)介
- 創(chuàng)建oauth2-client模塊
- 修改授權(quán)服務(wù)器配置
- 網(wǎng)頁(yè)單點(diǎn)登錄演示
- 調(diào)用接口單點(diǎn)登錄演示
- oauth2-client添加權(quán)限校驗(yàn)
- 使用到的模塊
- 項(xiàng)目源碼地址
項(xiàng)目使用的Spring Cloud為Hoxton版本,,Spring Boot為2.2.2.RELEASE版本
摘要
Spring Cloud Security 為構(gòu)建安全的SpringBoot應(yīng)用提供了一系列解決方案,結(jié)合Oauth2可以實(shí)現(xiàn)單點(diǎn)登錄功能,,本文將對(duì)其單點(diǎn)登錄用法進(jìn)行詳細(xì)介紹,。
單點(diǎn)登錄簡(jiǎn)介
單點(diǎn)登錄(Single Sign On)指的是當(dāng)有多個(gè)系統(tǒng)需要登錄時(shí),用戶只需登錄一個(gè)系統(tǒng),,就可以訪問(wèn)其他需要登錄的系統(tǒng)而無(wú)需登錄,。
創(chuàng)建oauth2-client模塊
這里我們創(chuàng)建一個(gè)oauth2-client服務(wù)作為需要登錄的客戶端服務(wù),使用上一節(jié)中的oauth2-jwt-server服務(wù)作為授權(quán)服務(wù),,當(dāng)我們?cè)趏auth2-jwt-server服務(wù)上登錄以后,,就可以直接訪問(wèn)oauth2-client需要登錄的接口,來(lái)演示下單點(diǎn)登錄功能,。
在pom.xml中添加相關(guān)依賴:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<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>
在application.yml中進(jìn)行配置:
server:
port: 9501
servlet:
session:
cookie:
name: OAUTH2-CLIENT-SESSIONID
oauth2-service-url: http://localhost:9401
spring:
application:
name: oauth2-client
security:
oauth2:
client:
client-id: admin
client-secret: admin123456
user-authorization-uri: ${oauth2-service-url}/oauth/authorize
access-token-uri: ${oauth2-service-url}/oauth/token
resource:
jwt:
key-uri: ${oauth2-service-url}/oauth/token_key
在啟動(dòng)類上添加@EnableOAuth2Sso注解來(lái)啟用單點(diǎn)登錄功能:
@EnableOAuth2Sso
@SpringBootApplication
public class Oauth2ClientApplication {
public static void main(String[] args) {
SpringApplication.run(Oauth2ClientApplication.class, args);
}
}
添加接口用于獲取當(dāng)前登錄用戶信息:
@RestController
@RequestMapping("/user")
public class UserController {
@GetMapping("/getCurrentUser")
public Object getCurrentUser(Authentication authentication) {
return authentication;
}
}
修改授權(quán)服務(wù)器配置
修改oauth2-jwt-server模塊中的AuthorizationServerConfig類,將綁定的跳轉(zhuǎn)路徑為http://localhost:9501/login,,并添加獲取秘鑰時(shí)的身份認(rèn)證,。
@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://localhost:9501/login")
.scopes("all")
.authorizedGrantTypes("authorization_code", "password", "refresh_token");
}
@Override
public void configure(AuthorizationServerSecurityConfigurer security) throws Exception {
security.tokenKeyAccess("isAuthenticated()");
}
}
網(wǎng)頁(yè)單點(diǎn)登錄演示
啟動(dòng)oauth2-client服務(wù)和oauth2-jwt-server服務(wù),;
訪問(wèn)客戶端需要授權(quán)的接口http://localhost:9501/user/getCurrentUser會(huì)跳轉(zhuǎn)到授權(quán)服務(wù)的登錄界面,;
進(jìn)行登錄操作后跳轉(zhuǎn)到授權(quán)頁(yè)面;
授權(quán)后會(huì)跳轉(zhuǎn)到原來(lái)需要權(quán)限的接口地址,,展示登錄用戶信息,;
如果需要跳過(guò)授權(quán)操作進(jìn)行自動(dòng)授權(quán)可以添加autoApprove(true) 配置:
@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://localhost:9501/login")
.autoApprove(true)
.scopes("all")
.authorizedGrantTypes("authorization_code", "password", "refresh_token");
}
}
調(diào)用接口單點(diǎn)登錄演示
這里我們使用Postman來(lái)演示下如何使用正確的方式調(diào)用需要登錄的客戶端接口。
訪問(wèn)客戶端需要登錄的接口:http://localhost:9501/user/getCurrentUser
使用Oauth2認(rèn)證方式獲取訪問(wèn)令牌:
輸入獲取訪問(wèn)令牌的相關(guān)信息,,點(diǎn)擊請(qǐng)求令牌:
此時(shí)會(huì)跳轉(zhuǎn)到授權(quán)服務(wù)器進(jìn)行登錄操作:
登錄成功后使用獲取到的令牌:
最后請(qǐng)求接口可以獲取到如下信息:
{
"authorities": [{
"authority": "admin"
}],
"details": {
"remoteAddress": "0:0:0:0:0:0:0:1",
"sessionId": "6F5A553BB678C7272145FF9FF2A5D8F4",
"tokenValue": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VyX25hbWUiOiJqb3Vyd29uIiwic2NvcGUiOlsiYWxsIl0sImV4cCI6MTU3NzY4OTc2NiwiYXV0aG9yaXRpZXMiOlsiYWRtaW4iXSwianRpIjoiZjAwYjVkMGUtNjFkYi00YjBmLTkyNTMtOWQxZDYwOWM4ZWZmIiwiY2xpZW50X2lkIjoiYWRtaW4iLCJlbmhhbmNlIjoiZW5oYW5jZSBpbmZvIn0.zdgFTWJt3DnAsjpQRU6rNA_iM7gVHX7E9bCyF73MOSM",
"tokenType": "bearer",
"decodedDetails": null
},
"authenticated": true,
"userAuthentication": {
"authorities": [{
"authority": "admin"
}],
"details": null,
"authenticated": true,
"principal": "jourwon",
"credentials": "N/A",
"name": "jourwon"
},
"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": "jourwon",
"credentials": "",
"name": "jourwon"
}
oauth2-client添加權(quán)限校驗(yàn)
添加配置開(kāi)啟基于方法的權(quán)限校驗(yàn):
@Configuration
@EnableGlobalMethodSecurity(prePostEnabled = true)
@Order(101)
public class SecurityConfig extends WebSecurityConfigurerAdapter {
}
在UserController中添加需要admin權(quán)限的接口:
@RestController
@RequestMapping("/user")
public class UserController {
@PreAuthorize("hasAuthority('admin')")
@GetMapping("/auth/admin")
public Object adminAuth() {
return "Has admin auth!";
}
}
訪問(wèn)需要admin權(quán)限的接口:http://localhost:9501/user/auth/admin
使用沒(méi)有admin 權(quán)限的賬號(hào),,比如andy:123456 獲取令牌后訪問(wèn)該接口,會(huì)發(fā)現(xiàn)沒(méi)有權(quán)限訪問(wèn),。
使用到的模塊
springcloud-learning
├── oauth2-jwt-server -- 使用jwt的oauth2認(rèn)證測(cè)試服務(wù)
└── oauth2-client -- 單點(diǎn)登錄的oauth2客戶端服務(wù)
項(xiàng)目源碼地址
GitHub項(xiàng)目源碼地址
|