既上一篇获取用户信息,又找到了另一种获取用户信息的方法,在这做下介绍 本方法获取用户信息使用的是 token-info-uri user-info-uri方式移步
资源服务配置文件
当使用token-info-uri时,默认user-info-uri不生效,loadBalanced:集群配置
security:
oauth2:
resource:
loadBalanced: true
user-info-uri: http://service-auth1/users/current
token-info-uri: http://service-auth/oauth/check_token
client:
client-secret: 123456
access-token-uri: http://service-auth/oauth/token
grant-type: password,client_credentials,refresh_token,authorization_code
scope: all
client-id: client
资源服务器配置
@Configuration
@EnableResourceServer
@EnableGlobalMethodSecurity(prePostEnabled = true)
public class ResourceServerConfiguration extends ResourceServerConfigurerAdapter {
@Resource
private ResourceServerProperties resourceServerProperties;
@Resource
private OAuth2ClientProperties oAuth2ClientProperties;
@Override
public void configure(HttpSecurity http) throws Exception {
http.csrf().disable();
http.authorizeRequests()
.antMatchers("/oauth/**").permitAll()
.anyRequest().authenticated();
}
@Override
public void configure(ResourceServerSecurityConfigurer resources) throws Exception {
resources
.tokenServices(tokenServices())
.authenticationEntryPoint(new CustomAuthenticationEntryPoint())
.accessDeniedHandler(new CustomAccessDeniedHandler());
}
@Bean
@Primary
public ResourceServerTokenServices tokenServices() {
RemoteTokenServices remoteTokenServices = new RemoteTokenServices();
remoteTokenServices.setCheckTokenEndpointUrl(resourceServerProperties.getTokenInfoUri());
remoteTokenServices.setClientId(oAuth2ClientProperties.getClientId());
remoteTokenServices.setClientSecret(oAuth2ClientProperties.getClientSecret());
remoteTokenServices.setRestTemplate(restTemplate());
DefaultAccessTokenConverter defaultAccessTokenConverter = new DefaultAccessTokenConverter();
defaultAccessTokenConverter.setUserTokenConverter(new CommonUserConverter());
remoteTokenServices.setAccessTokenConverter(defaultAccessTokenConverter);
return remoteTokenServices;
}
@Bean
@LoadBalanced
public RestTemplate restTemplate() {
RestTemplate restTemplate = new RestTemplate();
List<HttpMessageConverter<?>> converters = restTemplate.getMessageConverters();
List<HttpMessageConverter<?>> convertersValid = new ArrayList<>();
for (HttpMessageConverter<?> converter : converters) {
if (converter instanceof MappingJackson2HttpMessageConverter || converter instanceof MappingJackson2XmlHttpMessageConverter) {
continue;
}
convertersValid.add(converter);
}
convertersValid.add(new FastJsonHttpMessageConverter());
restTemplate.setMessageConverters(convertersValid);
return restTemplate;
}
}
重写UserAuthenticationConverter
public class CommonUserConverter implements UserAuthenticationConverter {
private static final String N_A = "N/A";
@Override
public Map<String, ?> convertUserAuthentication(Authentication authentication) {
Map<String, Object> authMap = new LinkedHashMap<>();
authMap.put(USERNAME, authentication.getName());
if (authentication.getAuthorities() != null && !authentication.getAuthorities().isEmpty()) {
authMap.put(AUTHORITIES, AuthorityUtils.authorityListToSet(authentication.getAuthorities()));
}
return authMap;
}
@Override
public Authentication extractAuthentication(Map<String, ?> map) {
if (map.containsKey(USERNAME)) {
Collection<? extends GrantedAuthority> authorities = getAuthorities(map);
String userId = (String) map.get("id");
String username = (String) map.get("username");
LoginUser user = new LoginUser(userId, username, N_A, true, true, true, true, authorities);
return new UsernamePasswordAuthenticationToken(user, N_A, authorities);
}
return null;
}
private Collection<? extends GrantedAuthority> getAuthorities(Map<String, ?> map) {
Object authorities = map.get(AUTHORITIES);
if (authorities instanceof String) {
return AuthorityUtils.commaSeparatedStringToAuthorityList((String) authorities);
}
if (authorities instanceof Collection) {
return AuthorityUtils.commaSeparatedStringToAuthorityList(StringUtils.collectionToCommaDelimitedString((Collection<?>) authorities));
}
throw new IllegalArgumentException("Authorities must be either a String or a Collection");
}
}
如果出现问题
import org.springframework.security.oauth2.provider.token.RemoteTokenServices;
点进RemoteTokenServices中,打断点测试
最后
在配置restTemplate的时候要清掉自带的xml返回值类型,要不然restTemplate会只得到xml参数,导致解析成map时里面全部为String,导致验证失败 这个方法配置起来比较麻烦,但是还是可以用的,如果嫌麻烦,该方法比较简单 user-info-uri方式移步
|