【发布时间】:2015-05-05 20:07:52
【问题描述】:
所以,我有一个 oAuth2 应用程序,它是 jHipster 应用程序(使用 mongodb)。我想将 3 个资源应用程序连接到该应用程序,但它们都应该共享相同的用户群,这样用户应该只能登录一次。
有没有办法在 Spring Boot 中使用 jHipster 配置多个资源,这样它就不会是一个单独的客户端,在访问资源之前需要用户名和密码?
还有如何为每个资源服务器指定用户角色?
所有的app都是基于spring-boot的。
下图是我想要完成的简单视图。
所以 OAuth2 应用具有授权服务器配置:
@Configuration
@EnableAuthorizationServer
protected static class AuthorizationServerConfiguration extends
AuthorizationServerConfigurerAdapter implements EnvironmentAware {
private static final String ENV_OAUTH = "authentication.oauth.";
private static final String PROP_CLIENTID = "clientid";
private static final String PROP_SECRET = "secret";
private static final String PROP_TOKEN_VALIDITY_SECONDS = "tokenValidityInSeconds";
private RelaxedPropertyResolver propertyResolver;
@Inject
private OAuth2AccessTokenRepository oAuth2AccessTokenRepository;
@Inject
private OAuth2RefreshTokenRepository oAuth2RefreshTokenRepository;
@Bean
public TokenStore tokenStore() {
return new MongoDBTokenStore(oAuth2AccessTokenRepository,
oAuth2RefreshTokenRepository);
}
@Inject
@Qualifier("authenticationManagerBean")
private AuthenticationManager authenticationManager;
@Override
public void configure(AuthorizationServerEndpointsConfigurer endpoints)
throws Exception {
endpoints.tokenStore(tokenStore()).authenticationManager(
authenticationManager);
}
@Override
public void configure(ClientDetailsServiceConfigurer clients)
throws Exception {
clients.inMemory()
.withClient("app-auth")
.scopes("read", "write")
.authorities(AuthoritiesConstants.ADMIN, AuthoritiesConstants.USER)
.authorizedGrantTypes("password", "refresh_token")
.secret(propertyResolver.getProperty(PROP_SECRET))
.accessTokenValiditySeconds(propertyResolver.getProperty(PROP_TOKEN_VALIDITY_SECONDS, Integer.class, 1800))
.and()
.withClient("app-A")
.scopes("read", "write")
.authorities(AuthoritiesConstants.ADMIN,AuthoritiesConstants.USER)
.authorizedGrantTypes("password", "refresh_token")
.secret(propertyResolver.getProperty(PROP_SECRET))
.accessTokenValiditySeconds(propertyResolver.getProperty(PROP_TOKEN_VALIDITY_SECONDS, Integer.class, 1800))
.and()
.withClient("app-A")
.scopes("read", "write")
.authorities(AuthoritiesConstants.ADMIN,AuthoritiesConstants.USER)
.authorizedGrantTypes("password", "refresh_token")
.secret(propertyResolver.getProperty(PROP_SECRET))
.accessTokenValiditySeconds(propertyResolver.getProperty(PROP_TOKEN_VALIDITY_SECONDS, Integer.class, 1800))
.and()
.withClient("app-C")
.scopes("read", "write")
.authorities(AuthoritiesConstants.ADMIN,AuthoritiesConstants.USER)
.authorizedGrantTypes("password", "refresh_token")
.secret(propertyResolver.getProperty(PROP_SECRET))
.accessTokenValiditySeconds(propertyResolver.getProperty(PROP_TOKEN_VALIDITY_SECONDS, Integer.class, 1800));
}
@Override
public void setEnvironment(Environment environment) {
this.propertyResolver = new RelaxedPropertyResolver(environment,
ENV_OAUTH);
}
}
OAuth2 应用也有资源服务器配置:
@Configuration
@EnableResourceServer
protected static class ResourceServerConfiguration extends
ResourceServerConfigurerAdapter {
@Inject
private Http401UnauthorizedEntryPoint authenticationEntryPoint;
@Inject
private AjaxLogoutSuccessHandler ajaxLogoutSuccessHandler;
@Override
public void configure(HttpSecurity http) throws Exception {
http.exceptionHandling()
.authenticationEntryPoint(authenticationEntryPoint)
.and()
.logout()
.logoutUrl("/api/logout")
.logoutSuccessHandler(ajaxLogoutSuccessHandler)
.and()
.csrf()
.requireCsrfProtectionMatcher(
new AntPathRequestMatcher("/oauth/authorize"))
.disable().headers().frameOptions().disable()
.sessionManagement()
.sessionCreationPolicy(SessionCreationPolicy.STATELESS)
.and().authorizeRequests().antMatchers("/api/authenticate")
.permitAll().antMatchers("/api/register").permitAll()
.antMatchers("/api/logs/**")
.hasAnyAuthority(AuthoritiesConstants.ADMIN)
.antMatchers("/api/**").authenticated()
.antMatchers("/metrics/**")
.hasAuthority(AuthoritiesConstants.ADMIN)
.antMatchers("/health/**")
.hasAuthority(AuthoritiesConstants.ADMIN)
.antMatchers("/trace/**")
.hasAuthority(AuthoritiesConstants.ADMIN)
.antMatchers("/dump/**")
.hasAuthority(AuthoritiesConstants.ADMIN)
.antMatchers("/shutdown/**")
.hasAuthority(AuthoritiesConstants.ADMIN)
.antMatchers("/beans/**")
.hasAuthority(AuthoritiesConstants.ADMIN)
.antMatchers("/configprops/**")
.hasAuthority(AuthoritiesConstants.ADMIN)
.antMatchers("/info/**")
.hasAuthority(AuthoritiesConstants.ADMIN)
.antMatchers("/autoconfig/**")
.hasAuthority(AuthoritiesConstants.ADMIN)
.antMatchers("/env/**")
.hasAuthority(AuthoritiesConstants.ADMIN)
.antMatchers("/trace/**")
.hasAuthority(AuthoritiesConstants.ADMIN)
.antMatchers("/api-docs/**")
.hasAuthority(AuthoritiesConstants.ADMIN)
.antMatchers("/protected/**").authenticated();
}
}
以及 App A 上的资源服务器(B 和 C 几乎相同):
@Configuration
@EnableResourceServer
protected static class ResourceServer extends ResourceServerConfigurerAdapter {
@Override
public void configure(HttpSecurity http) throws Exception {
http.requestMatchers().antMatchers("/api/**")
.and()
.authorizeRequests()
.antMatchers(HttpMethod.OPTIONS, "/**").permitAll()
.antMatchers(HttpMethod.GET, "/**").access("#oauth2.hasScope('read')")
.antMatchers(HttpMethod.PATCH, "/**").access("#oauth2.hasScope('write')")
.antMatchers(HttpMethod.POST, "/**").access("#oauth2.hasScope('write')")
.antMatchers(HttpMethod.PUT, "/**").access("#oauth2.hasScope('write')")
.antMatchers(HttpMethod.DELETE, "/**").access("#oauth2.hasScope('write')");
}
@Override
public void configure(ResourceServerSecurityConfigurer resources) throws Exception {
resources.resourceId("app-A");
}
}
【问题讨论】:
-
我不知道您为什么会认为这很困难。你有没有尝试过,但没有成功?
-
我试图在主应用程序上添加一个
@EnableAuthorizationServer和@EnableResourceServer,但是当我为其中一个应用程序请求一个令牌时,例如使用http://localhost:8080/oauth/token和username=user&password=user&grant_type=password&scope=read%20write&client_secret=mySecretOAuthSecret&client_id=app_A的帖子我得到一个弹出窗口,这是 Spring Security 的默认设置,要求我在请求令牌之前登录 -
/token 端点是反向通道。您不应该从浏览器访问它。也许你可以更详细地解释一下你做了什么。
-
我已经用示例代码更新了问题。
-
看起来(大部分)都还可以。我不知道为什么您需要在资源服务器中注销或保护 /authorize,但我认为他们不会做任何事情。客户在哪里?你在做什么来获得令牌,什么对你不起作用?
标签: spring spring-security spring-boot jhipster spring-security-oauth2