Spring boot #oauth2.hasScope弹簧靴+;钥匙斗篷
我想在spring boot+KeyClope中使用#oauth2.hasScope,获取带有grant_type=client_凭证的令牌。但它不起作用。这是我的密码,你能帮我吗Spring boot #oauth2.hasScope弹簧靴+;钥匙斗篷,spring-boot,keycloak,spring-security-oauth2,Spring Boot,Keycloak,Spring Security Oauth2,我想在spring boot+KeyClope中使用#oauth2.hasScope,获取带有grant_type=client_凭证的令牌。但它不起作用。这是我的密码,你能帮我吗 <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-oauth2-resource-server</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.security.oauth</groupId>
<artifactId>spring-security-oauth2</artifactId>
<version>2.3.7.RELEASE</version>
</dependency>
这是我的控制器
hasAnyAuthority(“范围电话”)可以,但“oauth2.hasScope”(“电话”)或“oauth2.hasScope”(“范围电话”)不工作,我收到403禁止
@RequestMapping(value = "/user", method = RequestMethod.GET)
@PreAuthorize("hasAnyAuthority('SCOPE_phone')")
public ResponseEntity<String> getUser() {
return ResponseEntity.ok("Hello User");
}
@RequestMapping(value = "/all-user", method = RequestMethod.GET)
@PreAuthorize("#oauth2.hasScope('phone')")
public ResponseEntity<String> getAllUser() {
return ResponseEntity.ok("Hello All User");
}
您是否使用KeyClope作为授权服务器?您有用于RemoteTokenServices的bean吗?
@Configuration
@EnableGlobalMethodSecurity(prePostEnabled = true, securedEnabled = true)
public class MethodSecurityConfiguration extends GlobalMethodSecurityConfiguration {
@Override
protected MethodSecurityExpressionHandler createExpressionHandler() {
return getOAuth2MethodSecurityExpressionHandler();
}
/**
*A security expression handler that can handle default method security expressions plus the set provided by OAuth2SecurityExpressionMethods using the variable oauth2 to access the methods. For example, the expression #oauth2.clientHasRole('ROLE_ADMIN') would invoke OAuth2SecurityExpressionMethods.clientHasRole(java.lang.String)
*By default the OAuth2ExpressionParser is used. If this is undesirable one can inject their own ExpressionParser using AbstractSecurityExpressionHandler.setExpressionParser(ExpressionParser).
*/
@Bean
public OAuth2MethodSecurityExpressionHandler getOAuth2MethodSecurityExpressionHandler() {
return new OAuth2MethodSecurityExpressionHandler();
}
}
@RequestMapping(value = "/user", method = RequestMethod.GET)
@PreAuthorize("hasAnyAuthority('SCOPE_phone')")
public ResponseEntity<String> getUser() {
return ResponseEntity.ok("Hello User");
}
@RequestMapping(value = "/all-user", method = RequestMethod.GET)
@PreAuthorize("#oauth2.hasScope('phone')")
public ResponseEntity<String> getAllUser() {
return ResponseEntity.ok("Hello All User");
}
{
"access_token": "eyJhbGciOiJSUzI1NiIsInR5cCIgOiAiSldUIiwia2lkIiA6ICI1MkRsOVNTMlREY0M5SkFtZmZ3ZE1BNjJkbFBreDlFMDdRSnhObF9sVDNJIn0.eyJleHAiOjE2MDM3ODQzNTMsImlhdCI6MTYwMzc4NDA1MywianRpIjoiY2Q2OWIzMDgtNDBmZi00YjJmLTljOWMtNjMyZjQxYTYyNzgwIiwiaXNzIjoiaHR0cDovL2xvY2FsaG9zdDo4MDgwL2F1dGgvcmVhbG1zL21pY3Jvc2VydmljZSIsImF1ZCI6ImFjY291bnQiLCJzdWIiOiIxZGExM2RjMy0yNDQ1LTRlZTQtYjFhNS0zNjc2YzYyMjY4OTciLCJ0eXAiOiJCZWFyZXIiLCJhenAiOiJtb2JpbGVyZXRhaWwiLCJzZXNzaW9uX3N0YXRlIjoiMmIxMzRlN2MtNDZiMS00MGNmLWIyMmYtODA3MDcyYWFjMGU0IiwiYWNyIjoiMSIsInJlYWxtX2FjY2VzcyI6eyJyb2xlcyI6WyJvZmZsaW5lX2FjY2VzcyIsInVtYV9hdXRob3JpemF0aW9uIl19LCJyZXNvdXJjZV9hY2Nlc3MiOnsibW9iaWxlcmV0YWlsIjp7InJvbGVzIjpbInVtYV9wcm90ZWN0aW9uIl19LCJhY2NvdW50Ijp7InJvbGVzIjpbIm1hbmFnZS1hY2NvdW50IiwibWFuYWdlLWFjY291bnQtbGlua3MiLCJ2aWV3LXByb2ZpbGUiXX19LCJzY29wZSI6InBob25lIHByb2ZpbGUgZW1haWwiLCJlbWFpbF92ZXJpZmllZCI6ZmFsc2UsImNsaWVudElkIjoibW9iaWxlcmV0YWlsIiwiY2xpZW50SG9zdCI6IjEyNy4wLjAuMSIsInByZWZlcnJlZF91c2VybmFtZSI6InNlcnZpY2UtYWNjb3VudC1tb2JpbGVyZXRhaWwiLCJjbGllbnRBZGRyZXNzIjoiMTI3LjAuMC4xIn0.acg7pPIK89AVFQT0oYrMmBwBGe4hy6PYrQCYdNbSOQA49p6FZ5ZCdqBtxKrxy2DYxgBJZNhMJ-PPZ_WrmRwTAS1H-Udo0Dj9o8VQLDyG2PsrVv8jdsCrrlSnPIg978HF6eP2bh49G4JYZjuLqzuX2h29voFWEMvtCjKGPYTwrwG24uYCKyEr_nCUV8_7Ky6hTyxl10xxnQ5qGjo1Acbhs-F4omgi6H2I2H17PUPVkKdeMKAbsVbubzbMbijgYAUf3j4KbsxEArJ6KC6ZZDsFIIB7-xMBMZD3OYjpn6-3Mt1s_QAlp4I9bdkSS2dNFtP3U6OmTnHCGyYgmScD8FTffw",
"expires_in": 300,
"refresh_expires_in": 1800,
"refresh_token": "eyJhbGciOiJIUzI1NiIsInR5cCIgOiAiSldUIiwia2lkIiA6ICIxOGM5ZmRiNy1mNzQ0LTQ2ZjktODQ4Ni0wMTFjNWVkOWNkZDIifQ.eyJleHAiOjE2MDM3ODU4NTMsImlhdCI6MTYwMzc4NDA1MywianRpIjoiMGJmOWMyZjItNjM5YS00OGVkLTgzNzUtM2M0YTE0ODc2ZGU0IiwiaXNzIjoiaHR0cDovL2xvY2FsaG9zdDo4MDgwL2F1dGgvcmVhbG1zL21pY3Jvc2VydmljZSIsImF1ZCI6Imh0dHA6Ly9sb2NhbGhvc3Q6ODA4MC9hdXRoL3JlYWxtcy9taWNyb3NlcnZpY2UiLCJzdWIiOiIxZGExM2RjMy0yNDQ1LTRlZTQtYjFhNS0zNjc2YzYyMjY4OTciLCJ0eXAiOiJSZWZyZXNoIiwiYXpwIjoibW9iaWxlcmV0YWlsIiwic2Vzc2lvbl9zdGF0ZSI6IjJiMTM0ZTdjLTQ2YjEtNDBjZi1iMjJmLTgwNzA3MmFhYzBlNCIsInNjb3BlIjoicGhvbmUgcHJvZmlsZSBlbWFpbCJ9.dG67rD5TPQLSQY69Fhdh9am_t_SZoiL9MEuufD6eOvU",
"token_type": "bearer",
"not-before-policy": 0,
"session_state": "2b134e7c-46b1-40cf-b22f-807072aac0e4",
"scope": "phone profile email"
}