Spring Security OAuth2の新機能–クレームの検証
1. 概要
このクイックチュートリアルでは、Spring Security OAuth2の実装を使用し、Spring Security OAuth 2.2.0.RELEASEで導入された新しいJwtClaimsSetVerifierを使用してJWTクレームを検証する方法を学習します。
2. Mavenの構成
まず、最新バージョンのspring-security-oauth2をpom.xmlに追加する必要があります。
org.springframework.security.oauth
spring-security-oauth2
2.2.0.RELEASE
3. トークンストアの構成
次に、リソースサーバーでTokenStoreを構成しましょう。
@Bean
public TokenStore tokenStore() {
return new JwtTokenStore(accessTokenConverter());
}
@Bean
public JwtAccessTokenConverter accessTokenConverter() {
JwtAccessTokenConverter converter = new JwtAccessTokenConverter();
converter.setSigningKey("123");
converter.setJwtClaimsSetVerifier(jwtClaimsSetVerifier());
return converter;
}
新しいベリファイアをJwtAccessTokenConverterに追加する方法に注意してください。
JwtTokenStoreの構成方法の詳細については、using JWT with Spring Security OAuthに関する記事を確認してください。
次のセクションでは、さまざまなタイプのクレーム検証ツールと、それらを連携させる方法について説明します。
4. IssuerClaimVerifier
次のように、IssuerClaimVerifierを使用して発行者の「iss」クレームを検証することにより、簡単に始めます。
@Bean
public JwtClaimsSetVerifier issuerClaimVerifier() {
try {
return new IssuerClaimVerifier(new URL("http://localhost:8081"));
} catch (MalformedURLException e) {
throw new RuntimeException(e);
}
}
この例では、発行者を確認するために単純なIssuerClaimVerifierを追加しました。 JWTトークンに発行者の「iss」クレームに対して異なる値が含まれている場合、単純なInvalidTokenExceptionがスローされます。
当然、トークンに発行者の「iss」クレームが含まれている場合、例外はスローされず、トークンは有効と見なされます。
5. カスタムクレームベリファイア
ただし、ここで興味深いのは、カスタムクレームベリファイアを作成することもできることです。
@Bean
public JwtClaimsSetVerifier customJwtClaimVerifier() {
return new CustomClaimVerifier();
}
これがどのように見えるかの簡単な実装を次に示します–user_nameクレームがJWTトークンに存在するかどうかを確認します。
public class CustomClaimVerifier implements JwtClaimsSetVerifier {
@Override
public void verify(Map claims) throws InvalidTokenException {
String username = (String) claims.get("user_name");
if ((username == null) || (username.length() == 0)) {
throw new InvalidTokenException("user_name claim is empty");
}
}
}
ここでJwtClaimsSetVerifierインターフェースを実装していることに注目してください。次に、verifyメソッドの完全なカスタム実装を提供します。これにより、必要なあらゆる種類のチェックに完全な柔軟性がもたらされます。
6. 複数のクレーム検証者を組み合わせる
最後に、次のように、DelegatingJwtClaimsSetVerifierを使用して複数のクレームベリファイアを組み合わせる方法を見てみましょう。
@Bean
public JwtClaimsSetVerifier jwtClaimsSetVerifier() {
return new DelegatingJwtClaimsSetVerifier(Arrays.asList(
issuerClaimVerifier(), customJwtClaimVerifier()));
}
DelegatingJwtClaimsSetVerifierは、JwtClaimsSetVerifierオブジェクトのリストを取得し、クレーム検証プロセスをこれらの検証者に委任します。
7. 簡単な統合テスト
実装が完了したので、単純なintegration testを使用してクレーム検証ツールをテストしましょう。
@RunWith(SpringRunner.class)
@SpringBootTest(
classes = ResourceServerApplication.class,
webEnvironment = WebEnvironment.RANDOM_PORT)
public class JwtClaimsVerifierIntegrationTest {
@Autowired
private JwtTokenStore tokenStore;
...
}
発行者を含まない(ただし、user_nameを含む)トークンから始めます。これは有効である必要があります。
@Test
public void whenTokenDontContainIssuer_thenSuccess() {
String tokenValue = "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9....";
OAuth2Authentication auth = tokenStore.readAuthentication(tokenValue);
assertTrue(auth.isAuthenticated());
}
これが有効である理由は単純です。最初の検証者は、発行者の主張がトークンに存在する場合にのみアクティブになります。 その主張が存在しない場合–検証者は開始しません。
次に、有効な発行者(http://localhost:8081)とuser_nameも含むトークンを見てみましょう。 これも有効である必要があります。
@Test
public void whenTokenContainValidIssuer_thenSuccess() {
String tokenValue = "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9....";
OAuth2Authentication auth = tokenStore.readAuthentication(tokenValue);
assertTrue(auth.isAuthenticated());
}
トークンに無効な発行者(http://localhost:8082)が含まれている場合、トークンは検証され、無効であると判断されます。
@Test(expected = InvalidTokenException.class)
public void whenTokenContainInvalidIssuer_thenException() {
String tokenValue = "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9....";
OAuth2Authentication auth = tokenStore.readAuthentication(tokenValue);
assertTrue(auth.isAuthenticated());
}
次に、トークンにuser_nameクレームが含まれていない場合、トークンは無効になります。
@Test(expected = InvalidTokenException.class)
public void whenTokenDontContainUsername_thenException() {
String tokenValue = "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9....";
OAuth2Authentication auth = tokenStore.readAuthentication(tokenValue);
assertTrue(auth.isAuthenticated());
}
そして最後に、トークンに空のuser_nameクレームが含まれている場合、それも無効です。
@Test(expected = InvalidTokenException.class)
public void whenTokenContainEmptyUsername_thenException() {
String tokenValue = "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9....";
OAuth2Authentication auth = tokenStore.readAuthentication(tokenValue);
assertTrue(auth.isAuthenticated());
}
8. 結論
この簡単な記事では、Spring Security OAuthの新しい検証機能について説明しました。
いつものように、完全なソースコードはover on GitHubで利用できます。