基于角色的授权:Oauth with OneLogin 和 Spring Security [英] Role based authorization: Oauth with OneLogin and Spring Security

查看:82
本文介绍了基于角色的授权:Oauth with OneLogin 和 Spring Security的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个 Spring Boot 应用程序,它使用 Oauth 和 OneLogin 作为授权服务器.现在,我想实现基于角色的授权,以仅向具有特定权限的用户公开某些 API.

I have a spring boot application which is using Oauth with OneLogin as the authorisation server. Now, I want to implement role based authorisation to expose certain APIs only to users with certain privileges.

我有属于组的用户.假设用户 A 属于admin"组和用户 B 不属于 admin 组.我的问题是如何使用这些组仅允许用户 A 访问某些 API.

I have users belonging to groups. Say user A belongs to "admin" group and user B does not belong to the admin group. My question is how can I use these groups to enable only user A to access certain APIs.

这是认证用户的信息供参考:

This is the information about the authenticated user for reference:

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"

我想像这样保护我的休息控制器:

I want to secure my rest controllers something like this:

@PreAuthorize("Belongs to group admin")
@RequestMapping(value = "/delete", method = RequestMethod.GET)
public string delete() {
  System.out.println("delete");
}

这是我的 application.yaml 文件

This is my application.yaml file

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 列表.

Since your application is also a resource server, you can use a custom JwtAuthenticationConverter to configure how the JWT gets converted to an Authentication object. Specifically for this case, you can configure how the JWT gets converted to the list of GrantedAuthorities.

默认情况下,资源服务器根据 范围" 声明填充 GrantedAuthorities.
如果 JWT 包含名称为 scope"scp" 的声明,则 Spring Security 将使用该声明中的值通过为每个声明添加前缀来构造权限SCOPE_" 的值.这就是为什么您会看到SCOPE_email"、SCOPE_groups"和SCOPE_groups"权限的原因.等

By default, the resource server populates the GrantedAuthorities based on the "scope" claim.
If the JWT contains a claim with the name "scope" or "scp", then Spring Security will use the value in that claim to construct the authorities by prefixing each value with "SCOPE_". That is why you see the authorities "SCOPE_email", "SCOPE_groups" etc

如果您想根据组"填充 GrantedAuthorities取而代之,您可以这样做:

If you want to populate the GrantedAuthorities based on the "groups" claim instead, you can do so like this:

@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')" 来限制对某些端点的访问.

Then you can use the expression "hasAuthority('YOUR_CUSTOM_GROUP_NAME')" to restrict access to certain endpoints.

这篇关于基于角色的授权:Oauth with OneLogin 和 Spring Security的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆