2

What I'm going to do is like this.

  1. post additional parameter when user submit on consent page.
  2. send posted additional parameter to redirect uri.

I've checked through AuthorizationRequestConverter that OAuth2AuthorizationCodeRequestAuthenticationToken has the parameter which user has uploaded.

But I don't know why OAuth2Authorization doesn't save additional parameters on Database. Cause of above I cant' reach to additional parameters and can't post data to redirect URI.


I've referred to this repository.

sjohnr/spring-authorization-server


Here's my auth server configuration

  1. AuthorizationServerConfig
    @Bean
    @Order(Ordered.HIGHEST_PRECEDENCE)
    public SecurityFilterChain authServerSecurityFilterChain(HttpSecurity http) throws Exception {
        OAuth2AuthorizationServerConfigurer<HttpSecurity> authorizationServerConfigurer =
                new OAuth2AuthorizationServerConfigurer<>();

        RequestMatcher endpointsMatcher = authorizationServerConfigurer.getEndpointsMatcher();

        authorizationServerConfigurer
                .authorizationEndpoint(authorizationEndPoint ->
                    authorizationEndPoint
                        .consentPage(CUSTOM_CONSENT_PAGE_URI)
                        .authorizationRequestConverter(customAuthorizationRequestConverter())
                        .authorizationResponseHandler(authorizationResponseHandler())
                )
                .withObjectPostProcessor(new ObjectPostProcessor<OAuth2AuthorizationCodeRequestAuthenticationProvider>() {
                    @Override
                    public <O extends OAuth2AuthorizationCodeRequestAuthenticationProvider> O postProcess(O object) {
                        object.setAuthenticationValidatorResolver(createDefaultAuthenticationValidatorResolver());
                        return object;
                    }
                });

        http
            .requestMatcher(endpointsMatcher)
            .authorizeRequests(authorizeRequest ->
                authorizeRequest.anyRequest().authenticated()
            )
            .formLogin(Customizer.withDefaults())
            .csrf(csrf -> csrf.ignoringRequestMatchers(endpointsMatcher))
            .apply(authorizationServerConfigurer);

        return http.build();
    }

    private AuthenticationConverter customAuthorizationRequestConverter() {
        final OAuth2AuthorizationCodeRequestAuthenticationConverter delegate = new OAuth2AuthorizationCodeRequestAuthenticationConverter();

        return (request) -> {
            OAuth2AuthorizationCodeRequestAuthenticationToken authorizationCodeRequestAuthentication =
                    (OAuth2AuthorizationCodeRequestAuthenticationToken) delegate.convert(request);
            return authorizationCodeRequestAuthentication;
        };
    }

    // ... validator and authorizationResponseHandler are same as reference
  1. Authentication Provider
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.http.HttpStatus;
import org.springframework.security.authentication.AuthenticationProvider;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.AuthenticationException;
import org.springframework.stereotype.Component;

@RequiredArgsConstructor
@Component
@Slf4j
public class CustomAuthenticationProvider implements AuthenticationProvider {

    private final UserMapper userMapper;

    @Override
    public Authentication authenticate(Authentication authentication) throws AuthenticationException {
        String username = authentication.getName();
        String password = authentication.getCredentials().toString();

        User user = getUser(username);
        validatePassword(username, user.getPassword(), password);

        return new UsernamePasswordAuthenticationToken(username, password, user.getAuthorities());
    }

    private User getUser(String username) {
        User user = userMapper.fetchUserByUsername(username);
        if (user == null)
            throw new BusinessException("oauth.user.0100", HttpStatus.NOT_FOUND);
        return user;
    }

    private void validatePassword(String username, String userPassword, String reqPassword) {
        if(StringUtils.equals(userPassword, userMapper.fetchEncryptPassword(reqPassword)))
            return;

        userMapper.updateFailedLoginCount(username);
        throw new BusinessException("oauth.user.0100", HttpStatus.NOT_FOUND);
    }

    @Override
    public boolean supports(Class<?> authentication) {
        return authentication.equals(
                UsernamePasswordAuthenticationToken.class);
    }
}
kwanikJang
  • 21
  • 4

0 Answers0