我目前正在开发一个用于Oauth2身份验证的spring应用程序,但是我在实现自定义ClientDetailsService时遇到了一些问题。
我不能使用常见的inMemory ou jdbc clientDetailsService,因为客户端信息没有存储在我的应用程序中,我从外部Web服务获取它们。但是,当我设置自定义ClientDetailService时,我不再获取access_confirmation页面(我得到一个空白页面)。
为了向您展示我的问题,我不使用我的应用程序,而是使用官方spring-security-oauth项目中的vanilla测试spring-security-oauth
这是应用程序代码:
@SpringBootApplication
@EnableResourceServer
@RestController
public class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
@RequestMapping("/")
public String home() {
return "Hello World";
}
@RequestMapping(value = "/", method = RequestMethod.POST)
@ResponseStatus(HttpStatus.CREATED)
public String create(@RequestBody MultiValueMap<String, String> map) {
return "OK";
}
@Configuration
@EnableAuthorizationServer
protected static class OAuth2Config extends AuthorizationServerConfigurerAdapter {
@Autowired
private AuthenticationManager authenticationManager;
@Override
public void configure(AuthorizationServerEndpointsConfigurer endpoints) throws Exception {
endpoints.authenticationManager(authenticationManager);
}
@Override
public void configure(AuthorizationServerSecurityConfigurer security) throws Exception {
security.checkTokenAccess("isAuthenticated()");
}
public ClientDetailsService clientDetailsService() {
return new ClientDetailsService() {
@Override
public ClientDetails loadClientByClientId(String clientId) throws ClientRegistrationException {
BaseClientDetails details = new BaseClientDetails();
details.setClientId(clientId);
details.setAuthorizedGrantTypes(Arrays.asList("authorization_code") );
details.setScope(Arrays.asList("read, trust"));
details.setResourceIds(Arrays.asList("oauth2-resource"));
Set<GrantedAuthority> authorities = new HashSet<GrantedAuthority>();
authorities.add(new SimpleGrantedAuthority("ROLE_CLIENT"));
details.setAuthorities(authorities);
return details;
}
};
} //*/
@Override
public void configure(ClientDetailsServiceConfigurer clients) throws Exception {
// @formatter:off
clients.withClientDetails(clientDetailsService());
/*clients.inMemory()
.withClient("test")
.authorizedGrantTypes("authorization_code")
.authorities("ROLE_CLIENT")
.scopes("read", "trust")
.resourceIds("oauth2-resource");
//*/
// @formatter:on
}
}
}
如您所见,我添加自定义clientDetailsService并更改ClientDetailsServiceconfigurer配置以设置它而不是内存clientDetailsService。
我的问题是,当我尝试获取令牌时,我在登录用户后不再获取access_confirmation页面。
我发现了我的问题,我在clientDetails中对范围的定义是错误的。我有Arrays.asList(“read,trust”)而不是Arrays.asList(“read”,“trust”)
我错过了什么吗?我是否必须在其他地方设置自定义clientDetailsService?
答案 0 :(得分:5)
尝试更改您的ClientDetails impl,如下所示:
public ClientDetailsService clientDetailsService() {
return new ClientDetailsService() {
@Override
public ClientDetails loadClientByClientId(String clientId) throws ClientRegistrationException {
BaseClientDetails details = new BaseClientDetails();
details.setClientId(clientId);
details.setAuthorizedGrantTypes(Arrays.asList("authorization_code") );
details.setScope(Arrays.asList("read, trust"));
details.setRegisteredRedirectUri(Collections.singleton("http://anywhere.com"));
details.setResourceIds(Arrays.asList("oauth2-resource"));
Set<GrantedAuthority> authorities = new HashSet<GrantedAuthority>();
authorities.add(new SimpleGrantedAuthority("ROLE_CLIENT"));
details.setAuthorities(authorities);
return details;
}
};
} //*/
答案 1 :(得分:0)
我正在尝试做类似的事情,但我遇到了一些不同的问题。希望你们能在这里帮助我。
我下面有一堂课
@Entity
@Table(name = "oauth_client_details")
public class CustomOAuthClientDetails extends BaseClientDetails{
/**
*
*/
private static final long serialVersionUID = -2792747663814219416L;
@Id
@Override
public String getClientId() {
return super.getClientId();
}
@Override
public String getClientSecret() {
return super.getClientSecret();
}
@Override
public Collection<GrantedAuthority> getAuthorities() {
return super.getAuthorities();
}
}
如下声明的存储库类
Optional<CustomOAuthClientDetails> customOAuthClientDetails = authClientDetailsRepository.findByClientId(clientId);
当我尝试像下面那样做时
details.setAuthorizedGrantTypes(customOAuthClientDetails.get().getAuthorizedGrantTypes());
我收到以下错误
Caused by: org.hibernate.MappingException: Could not determine type for: java.util.Collection, at table: oauth_client_details, for columns: [org.hibernate.mapping.Column(authorities)]
at org.hibernate.mapping.SimpleValue.getType(SimpleValue.java:499) ~[hibernate-core-5.4.26.Final.jar:5.4.26.Final]
at org.hibernate.mapping.SimpleValue.isValid(SimpleValue.java:466) ~[hibernate-core-5.4.26.Final.jar:5.4.26.Final]
at org.hibernate.mapping.Property.isValid(Property.java:227) ~[hibernate-core-5.4.26.Final.jar:5.4.26.Final]
at org.hibernate.mapping.PersistentClass.validate(PersistentClass.java:624) ~[hibernate-core-5.4.26.Final.jar:5.4.26.Final]
at org.hibernate.mapping.RootClass.validate(RootClass.java:267) ~[hibernate-core-5.4.26.Final.jar:5.4.26.Final]
at org.hibernate.boot.internal.MetadataImpl.validate(MetadataImpl.java:354) ~[hibernate-core-5.4.26.Final.jar:5.4.26.Final]
at org.hibernate.boot.internal.SessionFactoryBuilderImpl.build(SessionFactoryBuilderImpl.java:465) ~[hibernate-core-5.4.26.Final.jar:5.4.26.Final]
at org.hibernate.jpa.boot.internal.EntityManagerFactoryBuilderImpl.build(EntityManagerFactoryBuilderImpl.java:1259) ~[hibernate-core-5.4.26.Final.jar:5.4.26.Final]
at org.springframework.orm.jpa.vendor.SpringHibernateJpaPersistenceProvider.createContainerEntityManagerFactory(SpringHibernateJpaPersistenceProvider.java:58) ~[spring-orm-5.3.2.jar:5.3.2]
at org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean.createNativeEntityManagerFactory(LocalContainerEntityManagerFactoryBean.java:365) ~[spring-orm-5.3.2.jar:5.3.2]
at org.springframework.orm.jpa.AbstractEntityManagerFactoryBean.buildNativeEntityManagerFactory(AbstractEntityManagerFactoryBean.java:409) ~[spring-orm-5.3.2.jar:5.3.2]
... 21 common frames omitted