我目前正在开展一个项目,我们希望用户通过Facebook和其他OAuth2提供商登录。此外,REST api应该是无状态的。因此,不应创建/使用cookie / jsessionids。对于api的授权,在通过Facebook成功登录后,api会发布JWT。消耗其余api的webapp是使用AgularJS和satellizer构建的。我将代码缩减为minimal example available on github。
工作流程理念:
到目前为止工作
问题
webapp和其他api的组合" login / facebook?code = XXX"电话不起作用。我发现当你进行GET" login / facebook"时,你将被重定向到facebook,并在网址上附加一个附加状态参数。此外,当facebook重定向回api时,还会添加此状态参数。从我在网上找到的,这似乎是一种CSRF保护,对吧?而且我猜这个东西也创造了jsessionid cookie?
问题
示例代码
如前所述,我在GitHub上放了一个完整的最小例子。在这里,我将只发布WebSecurityConfigurerAdapter(希望)最重要的部分。 complete file is here.
@EnableOAuth2Client
@Configuration
public class OAuth2ClientConfigurer extends WebSecurityConfigurerAdapter {
@Autowired
private OAuth2ClientContext oAuth2ClientContext;
@Override
protected void configure(HttpSecurity httpSecurity) throws Exception {
httpSecurity
.csrf().disable()
.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS).enableSessionUrlRewriting(false).and()
.antMatcher("/**").authorizeRequests()
.antMatchers("/login/**").permitAll()
.anyRequest().authenticated().and()
.exceptionHandling().authenticationEntryPoint(new Http403ForbiddenEntryPoint()).and()
.addFilterBefore(statelessJwtAuthenticationFilter(), UsernamePasswordAuthenticationFilter.class)
.addFilterBefore(createSsoFilter(facebook(), facebookSuccessHandler(), "/login/facebook"), BasicAuthenticationFilter.class);
}
private OAuth2ClientAuthenticationProcessingFilter createSsoFilter(ClientResourceDetails clientDetails, AuthenticationSuccessHandler successHandler, String path) {
OAuth2ClientAuthenticationProcessingFilter ssoFilter = new OAuth2ClientAuthenticationProcessingFilter(path);
ssoFilter.setAllowSessionCreation(false);
OAuth2RestTemplate restTemplate = new OAuth2RestTemplate(clientDetails.getClient(), oAuth2ClientContext);
ssoFilter.setRestTemplate(restTemplate);
ssoFilter.setTokenServices(new UserInfoTokenServices(clientDetails.getResource().getUserInfoUri(), clientDetails.getClient().getClientId()));
ssoFilter.setAuthenticationSuccessHandler(successHandler);
return ssoFilter;
}
@Bean // handles the redirect to facebook
public FilterRegistrationBean oAuth2ClientFilterRegistration(OAuth2ClientContextFilter filter) {
FilterRegistrationBean registration = new FilterRegistrationBean();
registration.setFilter(filter);
registration.setOrder(-100);
return registration;
}
非常感谢你的帮助!
答案 0 :(得分:0)
这是可选的但建议使用的OAuth 2.0功能。它由授权服务器强制执行,正如您所假定的,其目的是防止csrf攻击。
从OAuth 2.0 RFC复制:
state
RECOMMENDED. An opaque value used by the client to maintain
state between the request and callback. The authorization
server includes this value when redirecting the user-agent back
to the client. The parameter SHOULD be used for preventing
cross-site request forgery as described in Section 10.12.