Java 无法获取用户详细信息:类org.springframework.security.oauth2.client.resource.OAuth2AccessDeniedException,无法获取新的访问权限
我正在处理Spring Cloud小POC,并得到以下错误。我试图使用使用此方法获得的令牌访问资源。你能告诉我怎么了吗 无法获取用户详细信息:类org.springframework.security.oauth2.client.resource.OAuth2AccessDeniedException,无法获取资源“null”的新访问令牌。未将提供程序管理器配置为支持它 SecurityConfigJava 无法获取用户详细信息:类org.springframework.security.oauth2.client.resource.OAuth2AccessDeniedException,无法获取新的访问权限,java,spring-boot,spring-security,spring-cloud,Java,Spring Boot,Spring Security,Spring Cloud,我正在处理Spring Cloud小POC,并得到以下错误。我试图使用使用此方法获得的令牌访问资源。你能告诉我怎么了吗 无法获取用户详细信息:类org.springframework.security.oauth2.client.resource.OAuth2AccessDeniedException,无法获取资源“null”的新访问令牌。未将提供程序管理器配置为支持它 SecurityConfig @Configuration @EnableGlobalMethodSecurity(prePo
@Configuration
@EnableGlobalMethodSecurity(prePostEnabled = true)
public class SecurityConfig extends GlobalMethodSecurityConfiguration {
@Override
protected MethodSecurityExpressionHandler createExpressionHandler() {
return new OAuth2MethodSecurityExpressionHandler();
}
}
CustomUserInfoTokenServices
public class CustomUserInfoTokenServices implements ResourceServerTokenServices {
protected final Log logger = LogFactory.getLog(getClass());
private static final String[] PRINCIPAL_KEYS = new String[] { "user", "username",
"userid", "user_id", "login", "id", "name" };
private final String userInfoEndpointUrl;
private final String clientId;
private OAuth2RestOperations restTemplate;
private String tokenType = DefaultOAuth2AccessToken.BEARER_TYPE;
private AuthoritiesExtractor authoritiesExtractor = new FixedAuthoritiesExtractor();
public CustomUserInfoTokenServices(String userInfoEndpointUrl, String clientId) {
this.userInfoEndpointUrl = userInfoEndpointUrl;
this.clientId = clientId;
}
public void setTokenType(String tokenType) {
this.tokenType = tokenType;
}
public void setRestTemplate(OAuth2RestOperations restTemplate) {
this.restTemplate = restTemplate;
}
public void setAuthoritiesExtractor(AuthoritiesExtractor authoritiesExtractor) {
this.authoritiesExtractor = authoritiesExtractor;
}
@Override
public OAuth2Authentication loadAuthentication(String accessToken)
throws AuthenticationException, InvalidTokenException {
Map<String, Object> map = getMap(this.userInfoEndpointUrl, accessToken);
if (map.containsKey("error")) {
this.logger.debug("userinfo returned error: " + map.get("error"));
throw new InvalidTokenException(accessToken);
}
return extractAuthentication(map);
}
private OAuth2Authentication extractAuthentication(Map<String, Object> map) {
Object principal = getPrincipal(map);
OAuth2Request request = getRequest(map);
List<GrantedAuthority> authorities = this.authoritiesExtractor
.extractAuthorities(map);
UsernamePasswordAuthenticationToken token = new UsernamePasswordAuthenticationToken(
principal, "N/A", authorities);
token.setDetails(map);
return new OAuth2Authentication(request, token);
}
private Object getPrincipal(Map<String, Object> map) {
for (String key : PRINCIPAL_KEYS) {
if (map.containsKey(key)) {
return map.get(key);
}
}
return "unknown";
}
@SuppressWarnings({ "unchecked" })
private OAuth2Request getRequest(Map<String, Object> map) {
Map<String, Object> request = (Map<String, Object>) map.get("oauth2Request");
String clientId = (String) request.get("clientId");
Set<String> scope = new LinkedHashSet<>(request.containsKey("scope") ?
(Collection<String>) request.get("scope") : Collections.<String>emptySet());
return new OAuth2Request(null, clientId, null, true, new HashSet<>(scope),
null, null, null, null);
}
@Override
public OAuth2AccessToken readAccessToken(String accessToken) {
throw new UnsupportedOperationException("Not supported: read access token");
}
@SuppressWarnings({ "unchecked" })
private Map<String, Object> getMap(String path, String accessToken) {
this.logger.info("Getting user info from: " + path);
try {
OAuth2RestOperations restTemplate = this.restTemplate;
if (restTemplate == null) {
BaseOAuth2ProtectedResourceDetails resource = new BaseOAuth2ProtectedResourceDetails();
resource.setClientId(this.clientId);
restTemplate = new OAuth2RestTemplate(resource);
}
OAuth2AccessToken existingToken = restTemplate.getOAuth2ClientContext()
.getAccessToken();
if (existingToken == null || !accessToken.equals(existingToken.getValue())) {
DefaultOAuth2AccessToken token = new DefaultOAuth2AccessToken(
accessToken);
token.setTokenType(this.tokenType);
restTemplate.getOAuth2ClientContext().setAccessToken(token);
}
return restTemplate.getForEntity(path, Map.class).getBody();
}
catch (Exception ex) {
this.logger.info("Could not fetch user details: " + ex.getClass() + ", "
+ ex.getMessage());
return Collections.<String, Object>singletonMap("error",
"Could not fetch user details");
}
}
公共类CustomUserInfoTokenServices实现ResourceServerTokenServices{
受保护的最终日志记录器=LogFactory.getLog(getClass());
私有静态最终字符串[]主体密钥=新字符串[]{“用户”、“用户名”,
“用户id”、“用户id”、“登录”、“id”、“名称”};
私有最终字符串userInfoEndpointUrl;
私有最终字符串clientId;
私有OAuth2RestOperations restTemplate;
私有字符串tokenType=DefaultOAuth2AccessToken.BEARER\u类型;
private Authorities Extractor Authorities Extractor=新的FixedAuthorities Extractor();
公共CustomUserInfoTokenServices(字符串userInfoEndpointUrl,字符串clientId){
this.userInfoEndpointUrl=userInfoEndpointUrl;
this.clientId=clientId;
}
公共void setTokenType(字符串tokenType){
this.tokenType=tokenType;
}
公共void setRestTemplate(OAuth2RestOperations restTemplate){
this.restTemplate=restTemplate;
}
public void setauthorities提取器(authorities提取器authorities提取器){
this.authoritiesExtractor=authoritiesExtractor;
}
@凌驾
公共OAuth2Authentication loadAuthentication(字符串访问令牌)
引发AuthenticationException,InvalidTokenException{
Map Map=getMap(this.userInfoEndpointUrl,accessToken);
if(map.containsKey(“错误”)){
this.logger.debug(“userinfo返回错误:”+map.get(“错误”));
抛出新的InvalidTokenException(accessToken);
}
返回身份验证(map);
}
私有OAuth2Authentication extractAuthentication(映射){
对象主体=getPrincipal(映射);
OAuth2Request请求=getRequest(映射);
列表权限=this.authorities提取器
.行政当局(地图);
UsernamePasswordAuthenticationToken=新的UsernamePasswordAuthenticationToken(
委托人,“不适用”,主管部门;
token.setDetails(map);
返回新的OAuth2Authentication(请求、令牌);
}
私有对象getPrincipal(映射){
for(字符串键:主键){
if(地图容器(图例)){
返回map.get(key);
}
}
返回“未知”;
}
@SuppressWarnings({“unchecked”})
私有OAuth2Request getRequest(映射){
映射请求=(Map)Map.get(“oauth2Request”);
String clientId=(String)request.get(“clientId”);
Set scope=newlinkedhashset(request.containsKey(“scope”)?
(Collection)request.get(“scope”):Collections.emptySet();
返回新的OAuth2Request(null,clientId,null,true,新的HashSet(scope),
空,空,空,空);
}
@凌驾
公共OAuth2AccessToken readAccessToken(字符串accessToken){
抛出新的UnsupportedOperationException(“不受支持:读取访问令牌”);
}
@SuppressWarnings({“unchecked”})
私有映射getMap(字符串路径、字符串访问令牌){
this.logger.info(“从:+路径获取用户信息”);
试一试{
OAuth2RestOperations restTemplate=this.restTemplate;
if(restTemplate==null){
BaseAuth2ProtectedResourceDetails资源=新的BaseAuth2ProtectedResourceDetails();
resource.setClientId(this.clientId);
restTemplate=新的OAuth2RestTemplate(资源);
}
OAuth2AccessToken existingToken=restTemplate.getOAuth2Client上下文()
.getAccessToken();
if(existingToken==null | |!accessToken.equals(existingToken.getValue())){
DefaultOAuth2AccessToken=新的DefaultOAuth2AccessToken(
accessToken);
token.setTokenType(this.tokenType);
restemplate.getOAuth2ClientContext().setAccessToken(令牌);
}
返回restemplate.getForEntity(path,Map.class).getBody();
}
捕获(例外情况除外){
this.logger.info(“无法获取用户详细信息:+ex.getClass()+”,”
+例如getMessage());
返回Collections.singletonMap(“错误”,
“无法获取用户详细信息”);
}
}
PluralsightSpringcloudM4SecureserviceApplication
@SpringBootApplication
@RestController
@EnableResourceServer
public class PluralsightSpringcloudM4SecureserviceApplication {
public static void main(String[] args) {
SpringApplication.run(PluralsightSpringcloudM4SecureserviceApplication.class, args);
}
// added
@Autowired
private ResourceServerProperties sso;
// added
@Bean
public ResourceServerTokenServices myUserInfoTokenServices() {
return new CustomUserInfoTokenServices(sso.getUserInfoUri(), sso.getClientId());
}
@RequestMapping("/tolldata")
@PreAuthorize("#oauth2.hasScope('toll_read') and hasAuthority('ROLE_OPERATOR')")
public ArrayList<TollUsage> getTollData() {
TollUsage instance1 = new TollUsage("200", "station150", "B65GT1W", "2016-09-30T06:31:22");
TollUsage instance2 = new TollUsage("201", "station119", "AHY673B", "2016-09-30T06:32:50");
TollUsage instance3 = new TollUsage("202", "station150", "ZN2GP0", "2016-09-30T06:37:01");
ArrayList<TollUsage> tolls = new ArrayList<TollUsage>();
tolls.add(instance1);
tolls.add(instance2);
tolls.add(instance3);
return tolls;
}
public class TollUsage {
public String Id;
public String stationId;
public String licensePlate;
public String timestamp;
public TollUsage() {
}
public TollUsage(String id, String stationid, String licenseplate, String timestamp) {
this.Id = id;
this.stationId = stationid;
this.licensePlate = licenseplate;
this.timestamp = timestamp;
}
}
}
@springboot应用程序
@RestController
@EnableResourceServer
公共类PluralsightSpringcloudM4SecureserviceApplication{
公共静态void main(字符串[]args){
run(PluralsightSpringcloudM4SecureserviceApplication.class,args);
}
//增加
@自动连线
私有资源服务器属性;
//增加
@豆子
公共资源服务器令牌服务myUserInfoTokenServices(){
返回新的CustomUserInfoTokenServices(sso.getUserInfoUri(),sso.getClientId());
}
@请求映射(“/tolldata”)
@预授权(#oauth2.hasScope('toll_read')和hasAuthority('ROLE_OPERATOR'))
公共ArrayList getTollData(){
收费站实例1=新收费站(“200”、“150站”、“B65GT1W”、“2016-09-30T06:31:22”);
收费站实例2=新收费站(“201”、“车站119”、“AHY673B”、“2016-09-30T06:32:50”);
收费站实例3=新收费站(“202”,“站”