我正在尝试使用具有外部本地身份验证服务器(WSO2身份验证服务器)的spring-cloud-security进行安全保护的spring-boot-web应用程序。我们正在使用OAuth2 OpenID Connect(JWT令牌)。使用WSO2身份验证服务器的Spring Cloud安全
我的应用程序将重定向到WSO2服务器,只适用于/ oauth2/authorize请求,但在尝试将authorization_code转换为access_token时失败。 spring-boot报告401认证错误。
我相信这是因为oauth2/token端点需要基本认证。
有人可以指导我如何使/ oauth2 /令牌请求使用基本认证标题与春季云安全?
这里是我的application.yml
spring:
oauth2:
sso:
home:
secure: false
path: /,/**/*.html
client:
accessTokenUri: https://URI:9443/oauth2/token
userAuthorizationUri: https://URI:9443/oauth2/authorize
clientId: id
clientSecret: secret
scope: openid
clientAuthenticationScheme: header
resource:
userInfoUri: https://URI:9443/oauth2/userinfo?schema=openid
这里是我的简单application.java
package demo;
import java.io.IOException;
import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.netflix.zuul.EnableZuulProxy;
import org.springframework.cloud.security.oauth2.sso.EnableOAuth2Sso;
import org.springframework.cloud.security.oauth2.sso.OAuth2SsoConfigurerAdapter;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.web.csrf.CsrfFilter;
import org.springframework.security.web.csrf.CsrfToken;
import org.springframework.security.web.csrf.CsrfTokenRepository;
import org.springframework.security.web.csrf.HttpSessionCsrfTokenRepository;
import org.springframework.web.filter.OncePerRequestFilter;
import org.springframework.web.util.WebUtils;
@SpringBootApplication
@EnableZuulProxy
@EnableOAuth2Sso
public class SpringOauth2WithWso2Application {
public static void main(String[] args) {
SpringApplication.run(SpringOauth2WithWso2Application.class, args);
}
@Configuration
protected static class SecurityConfiguration extends OAuth2SsoConfigurerAdapter {
@Override
public void match(RequestMatchers matchers) {
matchers.anyRequest();
}
@Override
public void configure(HttpSecurity http) throws Exception {
http.authorizeRequests().antMatchers("/index.html", "/home.html", "/")
.permitAll().anyRequest().authenticated().and().csrf()
.csrfTokenRepository(csrfTokenRepository()).and()
.addFilterAfter(csrfHeaderFilter(), CsrfFilter.class);
}
private Filter csrfHeaderFilter() {
return new OncePerRequestFilter() {
@Override
protected void doFilterInternal(HttpServletRequest request,
HttpServletResponse response, FilterChain filterChain)
throws ServletException, IOException {
CsrfToken csrf = (CsrfToken) request.getAttribute(CsrfToken.class
.getName());
if (csrf != null) {
Cookie cookie = WebUtils.getCookie(request, "XSRF-TOKEN");
String token = csrf.getToken();
if (cookie == null || token != null
&& !token.equals(cookie.getValue())) {
cookie = new Cookie("XSRF-TOKEN", token);
cookie.setPath("/");
response.addCookie(cookie);
}
}
filterChain.doFilter(request, response);
}
};
}
private CsrfTokenRepository csrfTokenRepository() {
HttpSessionCsrfTokenRepository repository = new HttpSessionCsrfTokenRepository();
repository.setHeaderName("X-XSRF-TOKEN");
return repository;
}
}
}
事实证明,错误是由于使用自签名证书的wso2身份服务器导致的。我们通过将-Djavax.net.debug = ssl添加到spring-boot启动命令来诊断它。我们通过将WSO2服务器的公共证书添加到spring-boot应用程序的java truststore来解决此问题。问题解决了。 – Bryce
这将是值得发布的完整答案否则这篇文章最终会浪费人们的时间,如果他们希望使用它来帮助他们将WSO2 IS集成到Spring Cloud Security(特别是Spring Security OAuth2)。例如,如果您希望将Spring Security OAuth2与WSO2 IS一起使用,则此问题/线程当然具有相关性:https://github.com/spring-cloud/spring-cloud-security/issues/63(请注意需要更改在尝试访问用户身份时,承载者承载者是链中的最后一步)。也可以将标题(使用WSO2 IS的Spring Cloud Security)更改为不太通用的东西。 –