在 Spring Boot 更新版本 3 的 Spring Core 版本 6 中将 Spring Security 与 OAuth 2.0 集成,而不使用 OpenID connect

问题描述 投票:0回答:2

我正在尝试使用 OAuth 2.0 将 Spring 应用程序与 Spring Boot 版本 3 中的 Spring Security 集成,如果使用客户端凭据,它工作正常并生成访问令牌,但我需要使用密码凭据获取访问令牌,即,我需要使用登录用户详细信息而不是客户详细信息。在 Spring Boot 3 的更新版本中,它到处都使用 open id,但我希望在不使用 open id connect 的情况下完成它。

我期待适当的结果,它允许通过在更新的 Spring Boot 版本 3 中使用 OAuth 2.0 在 Spring Security 中生成访问令牌来使用密码凭据访问应用程序,就像在 Spring Boot 版本 2.6.1 中一样。给我一个使用邮递员的例子。

spring-boot spring-security spring-oauth2 spring-boot-3
2个回答
0
投票
spring.security.oauth2.client.registration.client-app.client-id=test
spring.security.oauth2.client.registration.client-app.client-secret=111111
spring.security.oauth2.client.registration.client-app.redirect-uri={baseUrl}/login/oauth2/code/{registrationId}
spring.security.oauth2.client.registration.client-app.authorization-grant-type=password
spring.security.oauth2.client.registration.client-app.scope=message.read,message.write

spring.security.oauth2.client.provider.client-app.authorization-uri=${sso.host}/oauth/authorize
spring.security.oauth2.client.provider.client-app.token-uri=${sso.host}/oauth/token
spring.security.oauth2.client.provider.client-app.user-info-uri=${gateway.host}/api/user/current
spring.security.oauth2.client.provider.client-app.user-name-attribute=data 




@Bean
    public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
        return http
                .csrf(AbstractHttpConfigurer::disable)
                .formLogin(Customizer.withDefaults())
                .authorizeHttpRequests(c -> c.anyRequest().authenticated())
                .build();
    }


@Configuration(proxyBeanMethods = false)
@ConditionalOnProperty(prefix = "spring.security.oauth2.client.registration",name = "client-app.authorization-grant-type",havingValue = "password")
public class CustomAuthenticationProvider implements AuthenticationProvider {

    private static final String CLIENT_KEY = "client-app";

    private final OAuth2AuthorizedClientRepository authorizedClientRepository;
    private final ClientRegistrationRepository clientRegistrationRepository;

    private final DefaultOAuth2UserService defaultOAuth2UserService = new DefaultOAuth2UserService();
    private final PasswordOAuth2AuthorizedClientProvider provider = new PasswordOAuth2AuthorizedClientProvider();
    private final AuthenticationDetailsSource<HttpServletRequest, ?> authenticationDetailsSource = new WebAuthenticationDetailsSource();

    public CustomAuthenticationProvider(OAuth2AuthorizedClientRepository authorizedClientRepository,ClientRegistrationRepository clientRegistrationRepository) {
        this.authorizedClientRepository = authorizedClientRepository;
        this.clientRegistrationRepository = clientRegistrationRepository;
    }

    @Override
    public Authentication authenticate(Authentication authentication) throws AuthenticationException {
        ClientRegistration clientRegistration = clientRegistrationRepository.findByRegistrationId(CLIENT_KEY);
        OAuth2AuthorizationContext context = OAuth2AuthorizationContext.withClientRegistration(clientRegistration)
                .attribute(OAuth2AuthorizationContext.USERNAME_ATTRIBUTE_NAME,authentication.getName())
                .attribute(OAuth2AuthorizationContext.PASSWORD_ATTRIBUTE_NAME,authentication.getCredentials().toString())
                .principal(authentication)
                .build();

        OAuth2AuthorizedClient authorizedClient = provider.authorize(context);

        OAuth2UserRequest userRequest = new OAuth2UserRequest(clientRegistration,authorizedClient.getAccessToken());
        OAuth2User oAuth2User = defaultOAuth2UserService.loadUser(userRequest);
        OAuth2AuthenticationToken oauth2Authentication = new OAuth2AuthenticationToken(oAuth2User, oAuth2User.getAuthorities(),authorizedClient.getClientRegistration().getRegistrationId());

        ServletRequestAttributes attributes = (ServletRequestAttributes)RequestContextHolder.currentRequestAttributes();
        HttpServletRequest request = attributes.getRequest();
        oauth2Authentication.setDetails(authenticationDetailsSource.buildDetails(request));

        authorizedClientRepository.saveAuthorizedClient(authorizedClient, oauth2Authentication, request, attributes.getResponse());

        return oauth2Authentication;
    }

    @Override
    public boolean supports(Class<?> authentication) {
        return UsernamePasswordAuthenticationToken.class == authentication;
    }

}

0
投票

“PasswordOAuth2AuthorizedClientProvider”在建议的答案中已被弃用。

© www.soinside.com 2019 - 2024. All rights reserved.