我有一个spring-boot服务,使用OpenID Connect / OAuth2通过Okta Platform API对用户进行身份验证。当用户尝试访问我的服务时,他们会被重定向到Okta登录页面并进行身份验证,然后Okta将他们重定向回我的服务。
这是我的pom.xml的相关部分
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-oauth2</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-security</artifactId>
</dependency>
</dependencies>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>${spring-cloud.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
这是我的控制器代码:
@RestController
@EnableOAuth2Sso
@SpringBootApplication
public class Application {
@RequestMapping(path = "/", method = RequestMethod.GET)
public String home(Authentication auth) {
return "Home: " + auth.getName();
}
@RequestMapping(path = "/app", method = RequestMethod.POST)
public String app(Authentication auth) {
return "App: " + auth.getName();
}
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
}
这适用于第一个GET控制器方法,但对于第二个POST方法,我的服务要求我提供CSRF令牌。我想完全禁用CSRF检查,所以我将其添加到我的应用程序
@Configuration
@EnableOAuth2Sso
public class Config extends WebSecurityConfigurerAdapter {
@Override
public void configure(HttpSecurity http) throws Exception {
http.csrf().disable();
}
}
但是,在添加上述配置后,我的服务停止使用Okta对用户进行身份验证(不再将未经身份验证的请求重定向到Okta)。它使用null参数直接调用home()方法。
我按照此博文发布了我的服务https://developer.okta.com/blog/2017/03/21/spring-boot-oauth
如何在仍然使用Okta的OAuth2 SSO身份验证的情况下完全禁用CSRF?
答案 0 :(得分:2)
我遇到了完全相同的问题。在深入研究HttpSecurity类的工作方式后,我修改了configure()函数,如下所示:
@EnableWebSecurity
public static class WebSecurityConfig extends WebSecurityConfigurerAdapter
{
@Override
protected void configure(HttpSecurity http) throws Exception
{
http.authorizeRequests().anyRequest().authenticated().and().oauth2Login().and().csrf().disable();
}
}
添加构建器子句authorizeRequests()。anyRequest()。authenticated()。and()。oauth2Login()会强制控制器拦截具有OAuth身份验证的请求。您将在Spring HttpSecurity.java源代码中找到完整记录的文件。
请确保我修改了我所有的REST端点方法,以将标记作为参数包含在内,并且可以在原始版本的configure()方法中看到该标记为null,但是一旦添加了额外的子句,该标记便被包含在内
答案 1 :(得分:0)
您只需要为/ app端点禁用CSRF令牌。试试这个:
@Override
protected void configure(HttpSecurity http) throws Exception {
http.mvcMatcher("/app").csrf().disable();
}
答案 2 :(得分:0)
@Configuration
@EnableOAuth2Sso
public class Config extends WebSecurityConfigurerAdapter {
@Override
public void configure(HttpSecurity http) throws Exception {
http.csrf().disable();
}
}
这对我不起作用。相反,我为每个帖子请求添加了csrf标头。 这是获取csrf令牌的代码。
如果您使用百里香叶,则添加以下内容以在.html文件中获取CSRF令牌
<html xmlns:th="http://www.thymeleaf.org">
<script th:inline="javascript">
function getToken(){
var _csrf_token = [[${_csrf.token}]] ;
var _csrf_param_name = [[${_csrf.parameterName}]];
console.log(_csrf_token);
return _csrf_token;
}
</script>
</html>
然后将其作为标题放入您的ajax请求中
function sampleFunc(url, token) {
$.ajax({
type : 'POST',
contentType : "application/json",
url : '/storeTokens',
beforeSend : function(xhr) {
xhr.setRequestHeader('X-CSRF-TOKEN', token);
},
data : jsonObject
// dataType : 'html'
}).done(function(data) {
console.log("success");
}).fail(function(jqXhr) {
var a = jqXhr;
});
}
这对我有用。