问题
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
来源:https://stackoverflow.com/questions/40739135/change-authorities-roles-of-authenticated-user-from-sso-in-spring-oauth2-client