Bir dizi oAuth2 korumalı hizmet alıyorum. Şu anda böyle çalışır: istemci, kullanıcı adlarını ve şifresini kullanarak giriş yapar. Bunları bir jetonla değiştiriyorum. Jetonu seansta tutarım ve her defasında servis çağırmak istediğimi bildiririm. Çalışıyor, ama sorun, Spring Security oAuth2 desteğinin çoğunu kullanmadan tamamen manuel olarak yapıyorum. İşte böyle görünüyor:oAuth2 istemcisi Spring Security'de parola yardımı ile
<!-- Configure Authentication mechanism -->
<authentication-manager alias="authenticationManager">
<authentication-provider ref="oAuth2AuthenticationProvider"/>
</authentication-manager>
<beans:bean id="oAuth2AuthenticationProvider" class="my.custom.Oauth2AuthenticationProvider">
<beans:constructor-arg name="accessTokenUri" value="http://x.x.x.x/oauth/token"/>
<beans:constructor-arg name="clientId" value="myClientId"/>
<beans:constructor-arg name="clientSecret" value="myClientSecret"/>
<beans:constructor-arg name="scope">
<beans:list>
<beans:value>myScope</beans:value>
</beans:list>
</beans:constructor-arg>
</beans:bean>
<beans:bean id="resourceOwnerPasswordAccessTokenProvider" class="org.springframework.security.oauth2.client.token.grant.password.ResourceOwnerPasswordAccessTokenProvider"/>
Eğer kendim kimlik doğrulama sağlayıcısı tarafından yapılması görebileceğiniz gibi. Standart UsernamePasswordAuthenticationToken'ı kabul ediyor ancak gerçek OAuth2AccessToken'i de koruyan kendi uzantımı üretiyor ve böylece güvenlik bağlamında kalıyor.
public class Oauth2AuthenticationProvider implements AuthenticationProvider {
@Autowired
private ResourceOwnerPasswordAccessTokenProvider provider;
private String accessTokenUri;
private String clientId;
private String clientSecret;
private List<String> scope;
public Oauth2AuthenticationProvider(String accessTokenUri, String clientId, String clientSecret, List<String> scope) {
this.accessTokenUri = accessTokenUri;
this.clientId = clientId;
this.clientSecret = clientSecret;
this.scope = scope;
}
@Override
public Authentication authenticate(Authentication authentication) throws AuthenticationException {
String username = authentication.getName();
String password = authentication.getCredentials().toString();
OAuth2AccessToken token = obtainToken(username, password);
return handleLogonSuccess(authentication, token);
}
private OAuth2AccessToken obtainToken(String username, String password) {
ResourceOwnerPasswordResourceDetails passwordResourceDetails = new ResourceOwnerPasswordResourceDetails();
passwordResourceDetails.setUsername(username);
passwordResourceDetails.setPassword(password);
passwordResourceDetails.setClientId(clientId);
passwordResourceDetails.setClientSecret(clientSecret);
passwordResourceDetails.setScope(scope);
passwordResourceDetails.setAccessTokenUri(accessTokenUri);
DefaultAccessTokenRequest defaultAccessTokenRequest = new DefaultAccessTokenRequest();
OAuth2AccessToken token;
try {
token = provider.obtainAccessToken(passwordResourceDetails, defaultAccessTokenRequest);
} catch (OAuth2AccessDeniedException accessDeniedException) {
throw new BadCredentialsException("Invalid credentials", accessDeniedException);
}
return token;
}
public OAuth2AccessToken refreshToken(OAuth2AuthenticationToken authentication) {
OAuth2AccessToken token = authentication.getoAuth2AccessToken();
OAuth2RefreshToken refreshToken = token.getRefreshToken();
BaseOAuth2ProtectedResourceDetails resourceDetails = new BaseOAuth2ProtectedResourceDetails();
resourceDetails.setClientId(clientId);
resourceDetails.setClientSecret(clientSecret);
resourceDetails.setScope(scope);
resourceDetails.setAccessTokenUri(accessTokenUri);
OAuth2AccessToken newToken = provider.refreshAccessToken(resourceDetails, refreshToken, new DefaultAccessTokenRequest());
authentication.setoAuth2AccessToken(newToken);
return newToken;
}
public boolean supports(Class<?> authentication) {
return UsernamePasswordAuthenticationToken.class.isAssignableFrom(authentication);
}
private Authentication handleLogonSuccess(Authentication authentication, OAuth2AccessToken token) {
MyCustomOAuth2AuthenticationToken successAuthenticationToken = new MyCustomOAuth2AuthenticationToken(user, authentication.getCredentials(), calculateAuthorities(authentication), token);
return successAuthenticationToken;
}
public list<GrantedAuthority> calculateAuthorities(Authentication authentication) {
//my custom logic that assigns the correct role. e.g. ROLE_USER
}
}
Gördüğünüz gibi, temelde belirteci Ben sadece arka uç hizmetlerine her çağrı etmeden önce manuel olarak nerede güvenlik kapsamında kaldığından emin kılar. Benzer şekilde, her aramadan önce belirtecin tazeliğini kontrol edeceğim. Bu iyi çalışıyor, ama eminim ki, daha çok yapılandırma gerektirmeyen bir şekilde aynı şeyi elde etmek için Spring'in oauth ad alanını XML'de (Java config kullanmıyorum) kullanabilirim. Bulduğum çoğu örnek, umurumda değil ve sadece kafamı karıştırdığım oAuth sunucu uygulamasını içeriyor.
Bu konuda bana yardımcı olabilecek herhangi biri var mı?
: Bahar Boot ile? x-www-url-kodlanmış olarak – cosbor11