如何在 Spring Boot shell 应用程序中进行 oauth2 身份验证

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

我正在编写一个 Spring Boot shell 应用程序,它应该访问受 keycloak 保护的 REST API。在网络应用程序中一切都很好。浏览器将我重定向到 keycloak,然后将 keycloak 返回到我的应用程序,瞧,我已通过身份验证。

但是在没有浏览器的Cli/Shell应用程序中这似乎是不可能的。

我想要的只是获取一个访问令牌并将其附加到每个休息请求。像这样:

POST {{realmUri}}/protocol/openid-connect/token 
Content-Type: application/x-www-form-urlencoded
Accept: application/json

grant_type=password
&username={{username}}
&password={{userPassword}}
&client_id={{clientId}}
&client_secret={{clientSecret}}
&scope=openid+phone

返回访问令牌。我如何通过 spring security oauth 实现这一点? “资源所有者密码流程”应该是正确的,但没有实施。

但我认为这一定是可能的。

也许 OAuth2LoginAuthenticationProvider 可以完成这项工作。

spring spring-boot shell oauth keycloak
2个回答
2
投票

您可以使用 Spring Boot 中的 RestTemplate 向 Keycloak 令牌端点发送带有必要参数(grant_type、用户名、密码等)的 POST 请求,然后从响应中提取访问令牌并将其附加到您的 REST API 请求作为身份验证的承载令牌。


0
投票

我找到了一个解决方案,当然这种方式已被弃用。有人有更好的主意吗?如何使用未弃用的类实现相同的目标?

import org.springframework.boot.CommandLineRunner;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.autoconfigure.security.oauth2.client.OAuth2ClientProperties;
import org.springframework.boot.autoconfigure.security.oauth2.client.OAuth2ClientPropertiesMapper;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.oauth2.client.OAuth2AuthorizationContext;
import org.springframework.security.oauth2.client.PasswordOAuth2AuthorizedClientProvider;

import lombok.RequiredArgsConstructor;

@SpringBootApplication
@Configuration
@RequiredArgsConstructor
public class Application {

    public static void main(String[] args) {
        SpringApplication.run(Application.class, args);
    }

    private final OAuth2ClientProperties tokenServiceProperties;

    public String login(String username, String password) {
        var clientConfig = new OAuth2ClientPropertiesMapper(tokenServiceProperties).asClientRegistrations();
        OAuth2AuthorizationContext oAuth2AuthorizeContext = OAuth2AuthorizationContext
                .withClientRegistration(clientConfig.get("keycloak")).attributes(attrs -> {
                    attrs.put(OAuth2AuthorizationContext.USERNAME_ATTRIBUTE_NAME, username);
                    attrs.put(OAuth2AuthorizationContext.PASSWORD_ATTRIBUTE_NAME, password);
                    attrs.put(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_FORM_URLENCODED_VALUE);
                }).principal(new UsernamePasswordAuthenticationToken("no", "matter")).build();

        var user = new PasswordOAuth2AuthorizedClientProvider().authorize(oAuth2AuthorizeContext);
        return user.getAccessToken().getTokenValue();
    }

    @Bean
    CommandLineRunner run() {
        System.out.println(login("myapp_user_user", "password"));
        return aa -> {
        };
    }

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