当前位置: 首页 > 知识库问答 >
问题:

集成Spring Security OAuth2和Spring

佴波鸿
2023-03-14

我正在使用一个Spring Boot+Spring Security OAuth2应用程序,我相信它的灵感来自Dave Syer的示例。应用程序被配置为OAuth2授权服务器,具有使用资源所有者密码凭据流的单个公共客户端。成功的令牌被配置为JWT。

公共Angular客户机向/oauth/token发送一个POST请求,该请求带有包含客户机id和秘密的基本身份验证头(这是让客户机进行身份验证的最简单的方法,即使秘密不是私有的)。请求的正文包含用户名、密码和“password”的授予类型。

除了身份验证服务器之外,应用程序还是用户、团队和组织的RESTful资源服务器。

我正在尝试使用Spring Social添加一个额外的SSO身份验证流。我已经将Spring Social配置为通过/auth/[provider]通过外部提供程序进行身份验证;但是,以下请求不再正确设置SecurityContext。Spring Security OAuth服务器或客户端是否可能重写了SecurityContext?

如果我可以在Spring Social流之后正确设置SecurityContext,那么我就有了一个新的TokenGranter,它允许一个新的“Social”授予类型,它将检查预身份验证用户的SecurityContextHolder。

我对SecurityContext的具体问题(我认为这是Spring OAuth+Social integration的问题)的解决方案感兴趣,或者对外部提供者进行身份验证并从我们自己的身份验证服务器获取有效的JWT的不同方法感兴趣。

谢谢!

共有1个答案

严修谨
2023-03-14

我在一个Jhipster生成的web应用程序上遇到了类似的问题。最后,我决定使用Spring Social的SocialAuthenticationFilter选项(通过SpringSocialConfigureer)。成功的社交登录后,服务器自动生成并通过重定向到客户端应用程序返回“自己的”访问令牌。

以下是我的尝试:

@Configuration
@EnableResourceServer
protected static class ResourceServerConfiguration extends ResourceServerConfigurerAdapter implements EnvironmentAware {

    //...

    @Inject
    private AuthorizationServerTokenServices authTokenServices;

    @Override
    public void configure(HttpSecurity http) throws Exception {

        SpringSocialConfigurer socialCfg = new SpringSocialConfigurer();
        socialCfg
            .addObjectPostProcessor(new ObjectPostProcessor<SocialAuthenticationFilter>() {
                @SuppressWarnings("unchecked")
                public SocialAuthenticationFilter postProcess(SocialAuthenticationFilter filter){
                    filter.setAuthenticationSuccessHandler(
                            new SocialAuthenticationSuccessHandler(
                                    authTokenServices,
                                    YOUR_APP_CLIENT_ID
                            )
                        );
                    return filter;
                }
            });

        http
            //... lots of other configuration ...
            .apply(socialCfg);
    }        
}

SocialAuthenticationSuccessHandler类:

public class SocialAuthenticationSuccessHandler implements AuthenticationSuccessHandler {

    public static final String REDIRECT_PATH_BASE = "/#/login";
    public static final String FIELD_TOKEN = "access_token";
    public static final String FIELD_EXPIRATION_SECS = "expires_in";

    private final Logger log = LoggerFactory.getLogger(getClass());
    private final AuthorizationServerTokenServices authTokenServices;
    private final String localClientId;

    public SocialAuthenticationSuccessHandler(AuthorizationServerTokenServices authTokenServices, String localClientId){
        this.authTokenServices = authTokenServices;
        this.localClientId = localClientId;
    }

    @Override
    public void onAuthenticationSuccess(HttpServletRequest request,
            HttpServletResponse response, Authentication authentication)
                    throws IOException, ServletException {
        log.debug("Social user authenticated: " + authentication.getPrincipal() + ", generating and sending local auth");
        OAuth2AccessToken oauth2Token = authTokenServices.createAccessToken(convertAuthentication(authentication)); //Automatically checks validity
        String redirectUrl = new StringBuilder(REDIRECT_PATH_BASE)
            .append("?").append(FIELD_TOKEN).append("=")
            .append(encode(oauth2Token.getValue()))
            .append("&").append(FIELD_EXPIRATION_SECS).append("=")
            .append(oauth2Token.getExpiresIn())
            .toString();
        log.debug("Sending redirection to " + redirectUrl);
        response.sendRedirect(redirectUrl);
    }

    private OAuth2Authentication convertAuthentication(Authentication authentication) {
        OAuth2Request request = new OAuth2Request(null, localClientId, null, true, null,
                null, null, null, null);
        return new OAuth2Authentication(request,
                //Other option: new UsernamePasswordAuthenticationToken(authentication.getPrincipal(), "N/A", authorities)
                new PreAuthenticatedAuthenticationToken(authentication.getPrincipal(), "N/A")
                );
    }

    private String encode(String in){
        String res = in;
        try {
            res = UriUtils.encode(in, GeneralConstants.ENCODING_UTF8);
        } catch(UnsupportedEncodingException e){
            log.error("ERROR: unsupported encoding: " + GeneralConstants.ENCODING_UTF8, e);
        }
        return res;
    }
}

这样,只要在socialauthenticationsuccesshandler中设置相应的redirect_path_base,客户端应用程序将通过重定向到/#/login?access_token=my_access_token&expires_in=seconds_to_expiration来接收web应用程序的访问令牌。

希望有帮助。

 类似资料:
  • Spring是一个流行的Web框架,它提供易于集成与很多常见的网络任务。所以,问题是,为什么我们需要Spring,当我们有Struts2?Spring是超过一个MVC框架 - 它提供了许多其它好用的东西,这是不是在Struts。例如:依赖注入可以是有用的任何框架。在本章中,我们将通过一个简单的例子来看看如何集成Spring和Struts2一起。 首先,需要添加下列文件到项目的构建路径从Spring

  • 我正在尝试使用几个s-vaadin、jsp等实现一个应用程序。 它使用简单的,但后来我决定使用vaadin作为ui。 我创建了vaadin servlet(Spring的servlet也留下了)。我的看起来像这样 我创建了vaadin组件并根据我的需要对其进行了调整。我使用自动装配进行服务。 也是一个Spring bean。 < code>ProjectRepository是另一个spring b

  • 问题内容: 任何人都可以在此处粘贴简单的步骤来集成Spring Security和CAS,以进行单点登录和单点退出。注意我不需要任何基于角色的访问。我有一个已经与spring security集成的Web应用程序。现在,我尝试使用CAS执行SSO,但是出现此错误 这是我当前的spring security.xml 这是我的web.xml 这是我的Spring-rootcontext.xml 这是我

  • 问题内容: 我想使用Spring Batch和Spring Integration从数据库导入数据,并将它们写入文件,然后通过ftp将其传输到远程服务器。 但是我想我的问题是我不想为我的表创建域对象。我的查询是随机的,我想要一些可以读取数据并将其写入文件并进行传输的东西。 是否可以在不创建各自的域对象的情况下使用Spring Batch和Integration? 问题答案: 绝对。您可以将JDBC

  • 问题内容: 我有一个原型Storm应用程序,该应用程序读取STOMP流并将输出存储在HBase上。它可以工作,但不是很灵活,我试图与我们的其他应用程序以更一致的方式进行设置,但运气不好,无法确定当前使用Storm的方式。我们使用spring- jms类,但不是在标准spring方法中使用它们,而是在运行时创建它们并手动设置依赖项。 这个项目:https : //github.com/granthe

  • 我试图在我的Spring Boot项目中使用PowerMockito,但遇到了一个奇怪的问题。我正在使用PowerMockito模拟第三方库中的许多静态方法。 我的测试类遵循这个模式, 抽象测试类, 这很好,我可以模拟静态方法e.t.c,但当我引入第二个测试类时,我得到了以下错误:, 我的测试配置类如下所示,它加载了一个嵌入式Cassandra, 对我来说,它看起来像是试图添加一个已经存在的。有人

  • 我使用的是spring boot 2.1.7版本和keycloak-spring-boot-2-starter:4.0.0.final版本。这个keycloak-spring-boot-2-starter自动下载所需的keycloak适配器依赖项,对应于4.0.0..keycloak适配器依赖项的最终版本。现在,当我调用受keycloak保护的资源(rest api需要由keycloak服务器授权

  • 我正在尝试将球衣与Spring结合起来。 我对网络有疑问。xml配置。 这个例子包括SpringServlet: https://www.mkyong.com/webservices/jax-rs/jersey-spring-integration-example/ 但是另一个例子不包括SpringServlet。 https://github.com/jersey/jersey/blob/2.2