サンプルのOAuth2 Spring承認およびリソースサーバーを作成しようとしています。私の意図は、2つの別々のアプリケーションを実装することです - 一方は認可サーバーを表し、他方はリソースサーバーを表します。私はSpring Securityの初心者なので、私の仕事を完了するためのガイダンスが必要だと思います。OAuth2リソースサーバーと認証サーバーの接続
私はすでにインメモリトークンストア( "OAuth"という名前のアプリケーション)を使用して単純な認証サーバーを実装することができました。
AuthServerOAuth2Config.java
@Configuration
@EnableAuthorizationServer
public class AuthServerOAuth2Config extends AuthorizationServerConfigurerAdapter {
private static final String RESOURCE_ID = "myResource";
@Autowired
private UserApprovalHandler handler;
@Autowired
@Qualifier("authenticationManagerBean")
private AuthenticationManager authManager;
@Override
public void configure(ClientDetailsServiceConfigurer clients) throws Exception {
// @formatter:off
clients.inMemory()
.withClient("test")
.authorizedGrantTypes("password", "authorization_code", "refresh_token", "implicit")
.authorities("ROLE_CLIENT", "ROLE_TRUSTED_CLIENT")
.scopes("read", "write", "trust")
.resourceIds(RESOURCE_ID)
.secret("test")
.accessTokenValiditySeconds(300).//invalid after 5 minutes.
refreshTokenValiditySeconds(600);//refresh after 10 minutes.
// @formatter:on
}
@Override
public void configure(AuthorizationServerEndpointsConfigurer endpoints) throws Exception {
endpoints.tokenStore(tokenStore()).userApprovalHandler(handler).authenticationManager(authManager);
}
@Bean
public TokenStore tokenStore() {
return new InMemoryTokenStore();
}
}
予想通りOAuth2SecurityConfig.java
http://localhost:9081/OAuth/oauth/token?grant_type=password&username=admin&password=admin123
リターンへのアクセス
@Configuration
@EnableWebSecurity
public class OAuth2SecurityConfig extends WebSecurityConfigurerAdapter {
private static final Logger LOG = LoggerFactory.getLogger(OAuth2SecurityConfig.class);
@Autowired
private ClientDetailsService clientService;
@Autowired
private DataSource dataSource;
@Autowired
public void globalUserDetails(AuthenticationManagerBuilder auth) throws Exception {
// @formatter:off
auth.inMemoryAuthentication()
.withUser("javabycode").password("123456").roles("USER")
.and()
.withUser("admin").password("admin123").roles("ADMIN");
// @formatter:on
}
@Override
protected void configure(HttpSecurity http) throws Exception {
// @formatter:off
http
.csrf().disable()
.anonymous().disable()
.authorizeRequests()
.antMatchers("/oauth/token").permitAll();
// @formatter:on
}
@Override
@Bean
public AuthenticationManager authenticationManagerBean() throws Exception {
return super.authenticationManagerBean();
}
@Bean
public TokenStore tokenStore() {
return new JdbcTokenStore(dataSource);
}
@Bean
@Autowired
public TokenStoreUserApprovalHandler userApprovalHandler(TokenStore tokenStore) {
TokenStoreUserApprovalHandler handler = new TokenStoreUserApprovalHandler();
handler.setTokenStore(tokenStore);
handler.setRequestFactory(new DefaultOAuth2RequestFactory(clientService));
handler.setClientDetailsService(clientService);
return handler;
}
@Bean
@Autowired
public ApprovalStore approvalStore(TokenStore tokenStore) throws Exception {
TokenApprovalStore store = new TokenApprovalStore();
store.setTokenStore(tokenStore);
return store;
}
}
はトークンので、私は、認可サーバがOKに設定されていることを推測しています。
今、リソースサーバーの一部(「RestTest」という名前のアプリケーション)があります。私はRemoteTokenServices
を使っていくつかの例を見つけ、別のアプリにあるトークンサービスにアクセスしました。だからここまで私のリソースサーバーです。
OAuth2ResourceConfig.java
@Configuration
@EnableResourceServer
@EnableWebSecurity
public class OAuth2ResourceConfig extends ResourceServerConfigurerAdapter {
private static final String RESOURCE_ID = "myResource";
private TokenExtractor tokenExtractor = new BearerTokenExtractor();
@Override
public void configure(HttpSecurity http) throws Exception {
// @formatter:off
http.
anonymous().disable()
.requestMatchers().antMatchers("/v1/**")
.and().authorizeRequests()
.antMatchers("/v1/**").access("hasRole('ADMIN')")
.and().exceptionHandling().accessDeniedHandler(new OAuth2AccessDeniedHandler());
// @formatter:on
}
@Override
public void configure(ResourceServerSecurityConfigurer resources) throws
Exception {
resources.tokenServices(tokenService()).resourceId(RESOURCE_ID).stateless(true);
}
@Primary
@Bean
public RemoteTokenServices tokenService() {
RemoteTokenServices tokenService = new RemoteTokenServices();
tokenService.setCheckTokenEndpointUrl("http://localhost:9081/OAuth/oauth/check_token/");
tokenService.setClientId("test");
tokenService.setClientSecret("test");
return tokenService;
}
}
私は私のREST API(http://localhost:9081/RestTest/v1/foobar
)を確保しようとしているので、私は上記のような構成が正しい、正確であると考えていますか?問題は、v1/foobar
エンドポイント(郵便番号経由)にアクセスすると、認証なしでアクセスできることです。だから私は設定の一部を欠落していると思いますが、認証サーバーに正しく接続する方法を理解できません。言及するもう一つのこと - 私は春のブートを使用していないよ!
私は実際にサンプルを作成するためのガイダンスをいただきありがとうございます。ありがとう!
EDIT1:認証とリソースサーバーの両方にresourceId
を追加しました。 resourceId
は必須ですか?