Change Authorities/Roles of Authenticated User fro

2019-08-05 18:51发布

问题:

I am trying to authenticate a user from facebook and store it's username and provide custom permission to subset of users who will be admin for my application. My question is, How do I provide custom roles like "Admin" to the authenticated and authorize it in Oauth2Client.

@Configuration
class WebSecurityConfiguration extends GlobalAuthenticationConfigurerAdapter {

@Autowired
UserRepository userRepository;

@Override
public void init(AuthenticationManagerBuilder auth) throws Exception {
    auth.userDetailsService(userDetailsService());

}

@Bean
UserDetailsService userDetailsService() {
    return new UserDetailsService() {
        @Override
        public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
            User account = userRepository.findOne(username);
            if (account != null) {
                List<String> rolesList = userRepository.getRoles(username);
                String[] roles = new String[rolesList.size()];


                 // userRepository.findRoles List<String> roles =
                 //account.getUserroles().;
                 User user = new User(account.getUserssoid(), account.getSecretKey(), true, true, true, true,
                        AuthorityUtils.createAuthorityList(rolesList.toArray(roles)));

                return user;
            } else {
                throw new UsernameNotFoundException("could not find the user '" + username + "'");
            }
        }
    };
}
}

I want to do similar thing using OAuth2 Client.

Thanks

回答1:

What you need is custom UserInfoTokenServices Implementation with your ersistence repository as argument and then in your facebook filter use the custom UserInfoTokenServices insted of defaul like this:

    private Filter ssoFilter() {
    CompositeFilter filter = new CompositeFilter();
    List<Filter> filters = new ArrayList<>();
    filters.add(ssoFilter(facebook(), "/login/facebook"));
    filters.add(ssoFilter(google(), "/login/google"));
    filter.setFilters(filters);
    return filter;
}

private Filter ssoFilter(ClientResources client, String path) {
    OAuth2ClientAuthenticationProcessingFilter filter = new OAuth2ClientAuthenticationProcessingFilter(path);
    OAuth2RestTemplate template = new OAuth2RestTemplate(client.getClient(), oauth2ClientContext);
    filter.setRestTemplate(template);
    CustomSocialUserInfoTokenServices tokenServices = new CustomSocialUserInfoTokenServices(
            client.getResource().getUserInfoUri(), client.getClient().getClientId(), userRepository);
    tokenServices.setRestTemplate(template);
    filter.setTokenServices(tokenServices);

    return filter;
}

Than is your custom UserInfoTokenServices you can add your custom AuthoritiesExtractor like this private AuthoritiesExtractor authoritiesExtractor = new CustomSocialAuthoritiesExtractor(); There you can run your DB query or any logic to fetch your custom Authority and pass on to your clients.

Hope this helps



回答2:

You dont neccessaraly need a CustomSocialUserInfoTokenServices. Instead u could use existing UserInfoTokenServices and set your CustomSocialAuthoritiesExtractor.

private Filter ssoFilter(ClientResources client, String path) {
    ...
    UserInfoTokenServices tokenServices = new UserInfoTokenServices(client.getResource().getUserInfoUri(), client.getClient().getClientId());
    tokenServices.setRestTemplate(template);
    tokenServices.setAuthoritiesExtractor(new CustomSocialAuthoritiesExtractor());
    filter.setTokenServices(tokenServices);

return filter;

}

public class CustomSocialAuthoritiesExtractor implements AuthoritiesExtractor {
  @Override
  public List<GrantedAuthority> extractAuthorities(Map<String, Object> map) {
    String authorities = "ROLE_CUSTOMUSER";

    return AuthorityUtils.commaSeparatedStringToAuthorityList(authorities);
  }
}


回答3:

You can do it even simpler when you don't want to provide your own UserInfoTokenServices. Just provide an AuthoritiesExtractor bean in your security config.

@Bean
public AuthoritiesExtractor customAuthoritiesExtractor() {
    return new CustomAuthoritiesExtractor();
}

public class CustomAuthoritiesExtractor implements AuthoritiesExtractor {

    @Override
    public List<GrantedAuthority> extractAuthorities(Map<String, Object> map) {

        // map contains information from your OAuth profile provider

        boolean userExist = true; // TODO
        if (!userExist) {
            throw new BadCredentialsException("User does not exists");
        }

        String authorities = "ROLE_ADMIN"; // TODO your own roles
        return AuthorityUtils.commaSeparatedStringToAuthorityList(authorities);
    }
}

For more details refer to this tutorial: https://spring.io/guides/tutorials/spring-boot-oauth2/#_social_login_logout