spring-security-oauth2:1.0
を使用しているアプリケーションがあります。新しいバージョンspring-security-oauth2:2.0.7.RELEASE
に変更しようとしました。一部のクラスが削除され、一部のパッケージ構造が変更され、それらすべてを整理することができ、問題なくサーバーを起動できました。しかし、私はここで奇妙な問題に直面しています。
OAuth2 - 1.0 version
を使用すると、ユーザーがログインするときに、/oauth/token
でGET
リクエストを実行するために使用しました。次に例を示します。
以前は問題なく動作していました。
同じことを試してみると、まず TokenEndPoint.Java のロジックが原因で、GET
リクエストを実行できません。
private Set<HttpMethod> allowedRequestMethods = new HashSet<HttpMethod>(Arrays.asList(HttpMethod.POST));
@RequestMapping(value = "/oauth/token", method=RequestMethod.GET)
public ResponseEntity<OAuth2AccessToken> getAccessToken(Principal principal, @RequestParam
Map<String, String> parameters) throws HttpRequestMethodNotSupportedException {
if (!allowedRequestMethods.contains(HttpMethod.GET)) {
throw new HttpRequestMethodNotSupportedException("GET");
}
return postAccessToken(principal, parameters);
}
上記のURLと同じPOST
リクエストを作成しようとしましたが、エラーメッセージとともにInsufficientAuthenticationException
が表示されます
クライアント認証はありません。適切な認証フィルターを追加してみてください
これは、TokenEndpoint.Java
の次のPOST
リクエストコントローラが原因です。デバッグすると、principal
がnullであることがわかります。
@RequestMapping(value = "/oauth/token", method=RequestMethod.POST)
public ResponseEntity<OAuth2AccessToken> postAccessToken(Principal principal, @RequestParam
Map<String, String> parameters) throws HttpRequestMethodNotSupportedException {
//principal is null here
if (!(principal instanceof Authentication)) {
throw new InsufficientAuthenticationException(
"There is no client authentication. Try adding an appropriate authentication filter.");
}
.............
}
認証フィルターがあり、version 1.0
を使用するとうまく機能しました。これは私の設定の関連する部分です:
<authentication-manager xmlns="http://www.springframework.org/schema/security">
<authentication-provider user-service-ref="userDetailsService"/>
</authentication-manager>
<bean id="userDetailsService" class="com.hcl.nc.service.UserDetailsService">
<constructor-arg><ref bean="sessionFactory" /></constructor-arg>
</bean>
リクエストはauthentication-provider
によって認証され、token-endpoint
に送られるといつも思っていましたが、これは正しいフローではないようです。 version 2.0.7
を使用してアプリケーションをデバッグした後、フローについての理解に本当に疑問を抱きました。
なぜそれが以前のバージョンで機能したのか、なぜ今機能していないのかを誰かに説明してもらえますか?
OAuthトークンを取得するために別のことをする必要がありますか?
[〜#〜]注[〜#〜]:これらの質問をすでに確認しました: ここ 、 here 、 here 。しかし、正しい解決策を見つけることができませんでした。
以前のバージョンはわかりませんが、2.0.7については少しわかります。
あなたの問題はあなたのTokenEndpointセキュリティがあなたのクライアントをあなたのuserサービス。
TokenEndpointはBasicAuthenticationFilter
によって保護されています。デフォルトでは、このフィルターはAuthenticationManager
インスタンスを使用します。このインスタンス自体がAuthenticationProvider
を保持し、それ自体がUserDetailsService
のインスタンスに依存します。トリックは、UserDetailsService
のこの特定のインスタンスがclientベースでなければならず、serベースでなければならないことです。それがClientDetailsUserDetailsService
が存在する理由です。 ClientDetailsService
をUserDetailsService
に適合させます。
通常、フレームワークの構成クラスAuthorizationServerConfigurerAdapter
、@EnableAuthorizationServer
など.
私は同じ問題を抱えていて、私のapplication.ymlには次の行がありました:
servlet:
path: /auth
したがって、トークンアドレスは/auth/oauth/token
パスをapplication.ymlから削除して、トークンパスを次のようにします。
/oauth/token
そして、すべてが正常に動作します。
私はこの助けを願っています
次のエラーの問題の1つは、認証が実行されなかった可能性があります。 Springの古い実装でこの問題に遭遇しました。
それを確認する:
TokenEndpoint-> postAccessTokenメソッド。プリンシパルがnullでないかどうかを確認します。 nullの場合、基本的なAuthroziationが実行されなかったことを意味します。
フィルターを追加するソリューションの1つは、使用することでした:
@Configuration
public class FilterChainInitializer extends AbstractSecurityWebApplicationInitializer {
}
AbstractSecurityWebApplicationInitializerの詳細については、Spring docsを参照してください。
私の場合、私はこの設定を見つけました:
security.allowFormAuthenticationForClients(); //ここ
私の作品、それを試してみてください
@Configuration
@EnableAuthorizationServer
public class Oauth2Config extends AuthorizationServerConfigurerAdapter {
private static final Logger log = LoggerFactory.getLogger(Oauth2Config.class);
@Override
public void configure(AuthorizationServerSecurityConfigurer security) throws Exception {
security.allowFormAuthenticationForClients(); // here
}
@Override
public void configure(final ClientDetailsServiceConfigurer clients) throws Exception { // @formatter:off
clients.inMemory()
.withClient("unity-client")
.secret("unity")
.authorizedGrantTypes("authorization_code", "password", "client_credentials", "implicit", "refresh_token")
.scopes("foo", "read", "write")
.accessTokenValiditySeconds(3600) // 1 hour
.refreshTokenValiditySeconds(2592000) // 30 days
;
} // @formatter:on
@Override
public void configure(final AuthorizationServerEndpointsConfigurer endpoints) throws Exception {
}
}
問題は、すべてのリクエストを開いていることが原因である可能性があります。削除してください。
@Override
public void configure(WebSecurity web) throws Exception {
web
.ignoring()
.antMatchers("/**");
}