Spring Authorization Server ~ So registrieren Sie die Standardauthentifizierungsproviders nichtJava

Java-Forum
Anonymous
 Spring Authorization Server ~ So registrieren Sie die Standardauthentifizierungsproviders nicht

Post by Anonymous »

Ich versuche, die OAuth2 -Authentifizierung für eine App in einem Spring -Boot -Backend mit Spring Authorization Server zu implementieren. Mein Problem ist, dass ich eine benutzerdefinierte Logik habe, die seine eigenen Authentifizierungsantrieber verwendet, aber der Spring -Authentifizierungsserver automatisch eine ganze Reihe von Standardanbietern hinzufügt, die meine benutzerdefinierte Logik nicht verarbeiten und dann zum Absturz. Ich möchte herausfinden, wie ich die Standardauthentifizierungsproviders loswerden kann, damit keine Abstürze auftreten. In meinem eigenen Refresh -Token -Authentifizierungsprovider habe ich ein Bit, das überprüft, ob das Gerät_ID (ein benutzerdefiniertes Feld, das wir verwenden) mit dem gespeicherten Device_ID übereinstimmt und eine oATH2AuthenticationException auswirft, wenn dies nicht der Fall ist. < /P>

Code: Select all

        if (!providedDeviceId.equals(storedDeviceId)) {
String errorMessage = "Provided device ID '" + providedDeviceId
+ "' did not match stored device ID '" + storedDeviceId
+ "' for refresh token '" + refreshTokenValue + "'";
log.warn(errorMessage);
throw new OAuth2AuthenticationException(
new OAuth2Error(OAuth2ErrorCodes.INVALID_GRANT, errorMessage, null)
);
}
< /code>
Diese Logik funktioniert einwandfrei. In der Framework -Klasse org.springframework.security.authentication.providermanager 
funktioniert die Authentifizierungsmethode wie folgt:

Code: Select all

    @Override
public Authentication authenticate(Authentication authentication) throws AuthenticationException {
[...]
for (AuthenticationProvider provider : getProviders()) {
if (!provider.supports(toTest)) {
continue;
}
[...]
try {
result = provider.authenticate(authentication);
if (result != null) {
copyDetails(authentication, result);
break;
}
}
catch (AccountStatusException | InternalAuthenticationServiceException ex) {
prepareException(ex, authentication);
// SEC-546: Avoid polling additional providers if auth failure is due to
// invalid account status
throw ex;
}
catch (AuthenticationException ex) {
lastException = ex;
}
}
< /code>
Das heißt, es iteriert alle Authentifizierungsantrieber, die einen Authentifizierungstyp unterstützen, und bricht nur, wenn er erfolgreich ist, oder eine AccountStatusexception oder interneAuthenticationServiceException wird geworfen. Beachten Sie, dass es keine Authentifizierungspflicht bittet. So hätte ich erwartet, dass es funktioniert. Stattdessen wird es weiterhin über die verbleibenden Authentifizierungspfieber iteriert, die einen Authentifizierungstyp unterstützen. Und das führt mich zu meinem Problem: < /p>
getProviders()
gibt nicht nur einen, sondern zwei Anbieter zurück, die oAuth2RefreskenAuthenticationToken nominell unterstützen: Mein eigener benutzerdefinierter oauth2refreshtokenAuthProvider und die Standard -org.springFramework.security.oauth2uthorver.authoraThoring.Authentation.Authentation.OATH2RefReshtokenIntioning.Authenticate.OATH2REFRESHETUTICIERTIONIERTICIERTICIERTICTIONISICISICIERTICIERTICTIONICISICISICIERTICATIONIERTIERUNG. Auf der positiven Seite wird mein eigener Anbieter zuerst bezeichnet und wirft seine OAuth2AuthenticationException korrekt aus, wenn die nicht passenanpassungen von Device_ID. Leider wird die Spring OAuth2RefreshtokenAuthenticationProvider als nächst

Code: Select all

java.lang.IllegalArgumentException: value cannot be null
at org.springframework.util.Assert.notNull(Assert.java:181)
at org.springframework.security.oauth2.server.authorization.token.OAuth2TokenContext$AbstractBuilder.put(OAuth2TokenContext.java:219)
at org.springframework.security.oauth2.server.authorization.token.OAuth2TokenContext$AbstractBuilder.principal(OAuth2TokenContext.java:152)
at org.springframework.security.oauth2.server.authorization.authentication.OAuth2RefreshTokenAuthenticationProvider.authenticate(OAuth2RefreshTokenAuthenticationProvider.java:171)
at org.springframework.security.authentication.ProviderManager.authenticate(ProviderManager.java:182)
at org.springframework.security.authentication.ObservationAuthenticationManager.lambda$authenticate$1(ObservationAuthenticationManager.java:54)
at io.micrometer.observation.Observation.observe(Observation.java:564)
at org.springframework.security.authentication.ObservationAuthenticationManager.authenticate(ObservationAuthenticationManager.java:53)
< /code>
Ich könnte detailliert eingehen, warum diese Behauptung .Notnull fehlschlägt. Die Kurzversion ist, dass die Spring OAuth2ReFreshTokenAuthenticationProvider das Geräte_ID nicht überprüfen kann, da es sich um ein benutzerdefiniertes Feld handelt, und das verursacht Probleme weiter unten. Aber wirklich, das ist nicht der Punkt. Das Hauptproblem in meinen Augen ist hier, dass der Frühling OAuth2RefreshTokenAuthenticationProvider überhaupt aufgerufen wird. Was ich möchte, ist, dass mein benutzerdefinierter oAuth2RefreshtokenAuthProvider stattdessen und nicht zusätzlich zum Standardanbieter aufgerufen wird, da ich es geschrieben habe.  />  Mein OAuth2Config sieht so aus: < /p>
@Configuration
public class OAuth2Config {
@Bean
public SecurityFilterChain oAuth2FilterChain(
HttpSecurity http,
OAuth2PasswordGrantAuthProvider passwordAuthProvider,
OAuth2RefreshTokenAuthProvider refreshTokenAuthProvider,
PasswordGrantAuthenticationConverter passwordGrantAuthenticationConverter,
RefreshTokenAuthenticationConverter refreshTokenAuthenticationConverter
) throws Exception {
OAuth2AuthorizationServerConfigurer configurer =
new OAuth2AuthorizationServerConfigurer();

configurer.tokenEndpoint(token -> token
.accessTokenRequestConverter(
new DelegatingAuthenticationConverter(List.of(
passwordGrantAuthenticationConverter,
refreshTokenAuthenticationConverter
)))
.authenticationProvider(passwordAuthProvider)
.authenticationProvider(refreshTokenAuthProvider)
);

http
.securityMatcher("/oauth2/**")
.with(configurer, (authorizationServer) ->
authorizationServer.oidc(Customizer.withDefaults()))
.authorizeHttpRequests(
auth -> auth
.requestMatchers("/oauth2/token").permitAll()
.anyRequest().authenticated())
.csrf(csrf -> csrf.ignoringRequestMatchers("/oauth2/**"));

return http.build();
}

@Bean
public RegisteredClientRepository registeredClientRepository(
OAuth2Properties oAuth2Properties
) {
TokenSettings tokenSettings = TokenSettings.builder()
.accessTokenTimeToLive(Duration.ofMinutes(
oAuth2Properties.getFirstScope().getAccessTokenTimeToLiveInMinutes()))
.refreshTokenTimeToLive(Duration.ofDays(
oAuth2Properties.getFirstScope().getRefreshTokenTimeToLiveInDays()))
.reuseRefreshTokens(false)
.build();
RegisteredClient firstClient = RegisteredClient.withId(
UUID.randomUUID().toString())
.clientId(MyOAuth2.FIRST_CLIENT_ID)
.clientAuthenticationMethod(ClientAuthenticationMethod.NONE)
.authorizationGrantType(AuthorizationGrantType.PASSWORD)
.authorizationGrantType(AuthorizationGrantType.REFRESH_TOKEN)
.scope(MyOAuth2.FIRST_SCOPE)
.tokenSettings(tokenSettings)
.build();
return new InMemoryRegisteredClientRepository(firstClient);
}

@Bean
public OAuth2AuthorizationService authorizationService(
JdbcTemplate jdbcTemplate,
RegisteredClientRepository registeredClientRepository
) {
return new JdbcOAuth2AuthorizationService(
jdbcTemplate, registeredClientRepository);
}
}

Quick Reply

Change Text Case: 
   
  • Similar Topics
    Replies
    Views
    Last post