Role based authorization: Oauth with OneLogin and Spring Security

£可爱£侵袭症+ 提交于 2021-02-11 12:39:13

问题


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.

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");
}

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

回答1:


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.

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

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
}

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



来源:https://stackoverflow.com/questions/64645351/role-based-authorization-oauth-with-onelogin-and-spring-security

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!