基于角色的授权:Oauth with OneLogin and Spring Security
Role based authorization: Oauth with OneLogin and Spring Security
我有一个 spring 启动应用程序,它使用 Oauth 和 OneLogin 作为授权服务器。
现在,我想实现基于角色的授权,只向具有特定权限的用户公开某些 API。
我有属于组的用户。假设用户 A 属于“admin”组,而用户 B 不属于 admin 组。我的问题是如何使用这些组来仅允许用户 A 访问某些 API。
这是认证用户的信息,供参考:
authorities
0
authority "ROLE_USER" **//says ROLE_USER even when the user belongs to the admin group**
attributes
at_hash "xxxxx"
sub "xxxx"
iss "https://******/oidc/2"
groups
0 "Group A"
1 "Group B"
2 **"DEMO"**
3 **"DEMO Admin"** **//presence in this group should be considered for authorisation**
preferred_username "xxx"
given_name "xxxx"
nonce "xxxxxxx"
sid "xxxxxxx"
aud
0 "xxxxxxx"
updated_at "xxxxxx"
name "xxxxxx"
exp "xxxxxxx"
family_name "xxxxxx"
iat "xxxxxxxx"
email "xxxxxxxx"
idToken {…}
userInfo {…}
1
authority "SCOPE_email"
2
authority "SCOPE_groups"
3
authority "SCOPE_openid"
4
authority "SCOPE_profile"
我想像这样保护我的休息控制器:
@PreAuthorize("Belongs to group admin")
@RequestMapping(value = "/delete", method = RequestMethod.GET)
public string delete() {
System.out.println("delete");
}
这是我的 application.yaml 文件
server:
servlet:
context-path: /demo
spring:
security:
oauth2:
client:
registration:
onelogin:
client-id: *****
client-secret: *******
scope: openid,profile,email,groups
provider: onelogin
provider:
onelogin:
issuer-uri: https://******/oidc/2
由于您的应用程序也是一个资源服务器,您可以使用自定义 JwtAuthenticationConverter
来配置 JWT 如何转换为 Authentication
对象。特别针对这种情况,您可以配置 JWT 如何转换为 GrantedAuthorities
.
的列表
默认情况下,资源服务器根据 "scope"
声明填充 GrantedAuthorities
。
如果 JWT 包含名称为 "scope"
或 "scp"
的声明,则 Spring Security 将使用该声明中的值通过在每个值前加上 "SCOPE_"
前缀来构造权限。这就是为什么您会看到当局“SCOPE_email”、“SCOPE_groups”等
如果您想根据“群组”声明填充 GrantedAuthorities
,您可以这样做:
@Bean
public JwtAuthenticationConverter jwtAuthenticationConverter() {
JwtAuthenticationConverter converter = new JwtAuthenticationConverter();
converter.setJwtGrantedAuthoritiesConverter(new CustomJwtGrantedAuthoritiesConverter());
return converter;
}
public class CustomJwtGrantedAuthoritiesConverter implements Converter<Jwt, Collection<GrantedAuthority>> {
@Override
public Collection<GrantedAuthority> convert(Jwt jwt) {
Collection<GrantedAuthority> grantedAuthorities = new ArrayList<>();
for (String group : getGroups(jwt)) {
grantedAuthorities.add(new SimpleGrantedAuthority(group));
}
return grantedAuthorities;
}
}
private Collection<String> getGroups(Jwt jwt) {
Object groups = jwt.getClaim("groups");
// Convert groups to Collection of Strings based on your logic
}
然后您可以使用表达式 "hasAuthority('YOUR_CUSTOM_GROUP_NAME')"
来限制对某些端点的访问。
我有一个 spring 启动应用程序,它使用 Oauth 和 OneLogin 作为授权服务器。 现在,我想实现基于角色的授权,只向具有特定权限的用户公开某些 API。
我有属于组的用户。假设用户 A 属于“admin”组,而用户 B 不属于 admin 组。我的问题是如何使用这些组来仅允许用户 A 访问某些 API。
这是认证用户的信息,供参考:
authorities
0
authority "ROLE_USER" **//says ROLE_USER even when the user belongs to the admin group**
attributes
at_hash "xxxxx"
sub "xxxx"
iss "https://******/oidc/2"
groups
0 "Group A"
1 "Group B"
2 **"DEMO"**
3 **"DEMO Admin"** **//presence in this group should be considered for authorisation**
preferred_username "xxx"
given_name "xxxx"
nonce "xxxxxxx"
sid "xxxxxxx"
aud
0 "xxxxxxx"
updated_at "xxxxxx"
name "xxxxxx"
exp "xxxxxxx"
family_name "xxxxxx"
iat "xxxxxxxx"
email "xxxxxxxx"
idToken {…}
userInfo {…}
1
authority "SCOPE_email"
2
authority "SCOPE_groups"
3
authority "SCOPE_openid"
4
authority "SCOPE_profile"
我想像这样保护我的休息控制器:
@PreAuthorize("Belongs to group admin")
@RequestMapping(value = "/delete", method = RequestMethod.GET)
public string delete() {
System.out.println("delete");
}
这是我的 application.yaml 文件
server:
servlet:
context-path: /demo
spring:
security:
oauth2:
client:
registration:
onelogin:
client-id: *****
client-secret: *******
scope: openid,profile,email,groups
provider: onelogin
provider:
onelogin:
issuer-uri: https://******/oidc/2
由于您的应用程序也是一个资源服务器,您可以使用自定义 JwtAuthenticationConverter
来配置 JWT 如何转换为 Authentication
对象。特别针对这种情况,您可以配置 JWT 如何转换为 GrantedAuthorities
.
默认情况下,资源服务器根据 "scope"
声明填充 GrantedAuthorities
。
如果 JWT 包含名称为 "scope"
或 "scp"
的声明,则 Spring Security 将使用该声明中的值通过在每个值前加上 "SCOPE_"
前缀来构造权限。这就是为什么您会看到当局“SCOPE_email”、“SCOPE_groups”等
如果您想根据“群组”声明填充 GrantedAuthorities
,您可以这样做:
@Bean
public JwtAuthenticationConverter jwtAuthenticationConverter() {
JwtAuthenticationConverter converter = new JwtAuthenticationConverter();
converter.setJwtGrantedAuthoritiesConverter(new CustomJwtGrantedAuthoritiesConverter());
return converter;
}
public class CustomJwtGrantedAuthoritiesConverter implements Converter<Jwt, Collection<GrantedAuthority>> {
@Override
public Collection<GrantedAuthority> convert(Jwt jwt) {
Collection<GrantedAuthority> grantedAuthorities = new ArrayList<>();
for (String group : getGroups(jwt)) {
grantedAuthorities.add(new SimpleGrantedAuthority(group));
}
return grantedAuthorities;
}
}
private Collection<String> getGroups(Jwt jwt) {
Object groups = jwt.getClaim("groups");
// Convert groups to Collection of Strings based on your logic
}
然后您可以使用表达式 "hasAuthority('YOUR_CUSTOM_GROUP_NAME')"
来限制对某些端点的访问。