Spring Librariesを使用して実行されている基本的なインメモリOAuth2サーバーを取得しようとしています。 sparklrの例 に従っています。
現在、サーバーを構成し、ほとんどすべてが機能していますが、リソースサーバーから制限されたリソースにアクセスできません。
私のテストワークフロー:
oauth許可されたURIにアクセスしてOAuth2フローを開始します。 http:// localhost:8080/server/oauth/authorize?response_type = code&client_id = client
ログインページにリダイレクトします。 http:// localhost:8080/server/login
承認を処理し、設定済みのリダイレクトページにコードパラメータを付けてリダイレクトします。 http:// localhost:8080/client?code = HMJO4K
クライアントIDとシークレットを付与タイプとコードとともに使用して、基本認証を使用してGETリクエストを作成します。 http:// localhost:8080/server/oauth/token?grant_type = authorization_code&code = HMJO4K
Access_tokenを受け取り、代わりにトークンオブジェクトを更新する
{access_token: "f853bcc5-7801-42d3-9cb8-303fc67b0453" token_type: "bearer" refresh_token: "57100377-dea9-4df0-adab-62e33f2a1b49" expires_in:299 scope: "read write"}
Access_tokenを使用して制限されたリソースにアクセスしてみます。 http:// localhost:8080/server/me?access_token = f853bcc5-7801-42d3-9cb8-303fc67b045
無効なトークンの返信を受け取る
{エラー: "invalid_token" error_description: "無効なアクセストークン:f853bcc5-7801-42d3-9cb8-303fc67b0453"}
トークンuriに再度POSTしてトークンを更新します。 http:// localhost:8080/server/oauth/token?grant_type = refresh_token&refresh_token = 57100377-dea9-4df0-adab-62e33f2a1b49
新しいトークンを受け取る
{access_token: "ed104994-899c-4cd9-8860-43d5689a9420" token_type: "bearer" refresh_token: "57100377-dea9-4df0-adab-62e33f2a1b49" expires_in:300 scope: "read write"}
私は何を間違っているのか本当にわかりませんが、制限されたuriにアクセスする以外のすべてが機能しているようです。私の設定は次のとおりです。
@Configuration
public class Oauth2ServerConfiguration {
private static final String SERVER_RESOURCE_ID = "oauth2-server";
@Configuration
@EnableResourceServer
protected static class ResourceServerConfiguration extends ResourceServerConfigurerAdapter {
@Override
public void configure(ResourceServerSecurityConfigurer resources) {
resources.resourceId(SERVER_RESOURCE_ID);
}
@Override
public void configure(HttpSecurity http) throws Exception {
http
.sessionManagement()
.sessionCreationPolicy(SessionCreationPolicy.IF_REQUIRED)
.and().requestMatchers()
.antMatchers("/me")
.and().authorizeRequests()
.antMatchers("/me").access("#oauth2.clientHasRole('ROLE_CLIENT')")
;
}
}
@Configuration
@EnableAuthorizationServer
protected static class AuthotizationServerConfiguration extends AuthorizationServerConfigurerAdapter {
@Autowired
private ClientDetailsService clientDetailsService;
@Autowired
@Qualifier("authenticationManagerBean")
private AuthenticationManager authenticationManager;
@Override
public void configure(ClientDetailsServiceConfigurer clients) throws Exception {
clients.inMemory()
.withClient("client")
.resourceIds(SERVER_RESOURCE_ID)
.secret("secret")
.authorizedGrantTypes("authorization_code", "refresh_token")
.authorities("ROLE_CLIENT")
.scopes("read","write")
.redirectUris("http://localhost:8080/client")
.accessTokenValiditySeconds(300)
.autoApprove(true)
;
}
@Bean
public TokenStore tokenStore() {
return new InMemoryTokenStore();
}
@Override
public void configure(AuthorizationServerEndpointsConfigurer endpoints) throws Exception {
endpoints
.tokenStore(tokenStore())
.userApprovalHandler(userApprovalHandler())
.authenticationManager(authenticationManager)
;
}
@Override
public void configure(AuthorizationServerSecurityConfigurer oauthServer) throws Exception {
oauthServer.realm("oauth");
}
@Bean
public ApprovalStore approvalStore() throws Exception {
TokenApprovalStore store = new TokenApprovalStore();
store.setTokenStore(tokenStore());
return store;
}
@Bean
public UserApprovalHandler userApprovalHandler() throws Exception {
TokenStoreUserApprovalHandler handler = new TokenStoreUserApprovalHandler();
handler.setRequestFactory(new DefaultOAuth2RequestFactory(clientDetailsService));
handler.setClientDetailsService(clientDetailsService);
handler.setTokenStore(tokenStore());
return handler;
}
}
}
不足しているものがありますか、これに間違って近づいていますか?どんな助けも大歓迎です。
問題は、リソースサーバーと承認サーバーが同じトークンストア参照を取得していないことでした。配線がどのように正しく機能しなかったのかはわかりませんが、構成クラスで固定オブジェクトを使用すると、魅力のように機能しました。最終的には、永続性を備えたトークンストアに移行します。おそらく問題はありませんでした。
答えと助けをありがとう@OhadR!
最終的に、構成を単純化し、同じワークフローを実行して、うまくいきました。
@Configuration
public class Oauth2ServerConfiguration {
private static final String SERVER_RESOURCE_ID = "oauth2-server";
private static InMemoryTokenStore tokenStore = new InMemoryTokenStore();
@Configuration
@EnableResourceServer
protected static class ResourceServer extends ResourceServerConfigurerAdapter {
@Override
public void configure(ResourceServerSecurityConfigurer resources) throws Exception {
resources.tokenStore(tokenStore).resourceId(SERVER_RESOURCE_ID);
}
@Override
public void configure(HttpSecurity http) throws Exception {
http.requestMatchers().antMatchers("/me").and().authorizeRequests().antMatchers("/me").access("#oauth2.hasScope('read')");
}
}
@Configuration
@EnableAuthorizationServer
protected static class AuthConfig extends AuthorizationServerConfigurerAdapter {
@Autowired
private AuthenticationManager authenticationManager;
@Override
public void configure(AuthorizationServerEndpointsConfigurer endpoints) throws Exception {
endpoints.authenticationManager(authenticationManager).tokenStore(tokenStore).approvalStoreDisabled();
}
@Override
public void configure(ClientDetailsServiceConfigurer clients) throws Exception {
clients.inMemory()
.withClient("client")
.authorizedGrantTypes("authorization_code","refresh_token")
.authorities("ROLE_CLIENT")
.scopes("read")
.resourceIds(SERVER_RESOURCE_ID)
.secret("secret")
;
}
}
}
この投稿に出くわした人は、完全なsparklr/tonrの例ではなく、例えば、開始するのに必ずしも必要ではない追加の設定がたくさんあるので、例えばユニットテストをもっと見ることをお勧めします。
手順6は間違っています-この方法では脆弱であるため、アクセストークンをURLで送信しないでください。 GETではなく、POSTを使用します。
その上、私はあなたのステップ#1を理解していません-なぜ/ oauth/authorizeを呼び出すのですか?保護されたリソースを取得しようとすると、暗黙的に実行する必要があります。つまり、フローは次のように開始する必要があります。
Access_tokenを使用して、制限されたリソースにアクセスしてみます。 http:// localhost:8080/server/me
その後、ネゴシエーションは「舞台裏」で開始されます。「/ oauth/authorize」などへのリダイレクトです。
さらに、ステップ8では、「別のアクセストークン」を要求しているのではなく、「トークンの更新」を要求していることに注意してください。アクセストークンの有効期限が切れたように。
注:IDプロバイダーとリソースサーバーはtokenStoreを共有する必要があります!ここをお読みください: Spring Security OAuth2 pure resource server
HTH
これは私のために働く:
@Configuration
public class Oauth2ServerConfiguration {
private static final String SERVER_RESOURCE_ID = "oauth2-server";
@Autowired
private TokenStore tokenStore;
@Bean
public TokenStore tokenStore() {
return new InMemoryTokenStore();
}
@Configuration
@EnableResourceServer
protected static class ResourceServer extends ResourceServerConfigurerAdapter {
@Override
public void configure(ResourceServerSecurityConfigurer resources) throws Exception {
resources.tokenStore(tokenStore).resourceId(SERVER_RESOURCE_ID);
}
@Override
public void configure(HttpSecurity http) throws Exception {
// ... Not important at this stage
}
}
@Configuration
@EnableAuthorizationServer
protected static class AuthConfig extends AuthorizationServerConfigurerAdapter {
@Autowired
private AuthenticationManager authenticationManager;
@Override
public void configure(AuthorizationServerEndpointsConfigurer endpoints) throws Exception {
endpoints.authenticationManager(authenticationManager).tokenStore(tokenStore).approvalStoreDisabled();
}
@Override
public void configure(ClientDetailsServiceConfigurer clients) throws Exception {
//... Not important at this stage
}
}
}