Springboot + JWT + OAuth2 + AngularJS无状态会话

时间:2019-12-19 08:58:17

标签: angularjs spring-boot oauth-2.0 jwt

我正在尝试如下各种基于Java Spring的安全性实现

1。 JWT身份验证

  • 用户访问权限/
  • Springboot标识为受保护资源,并将用户重定向到/ login
  • 用户输入凭据,浏览器执行POST进行/ authenticate
  • 服务器验证凭据并生成JWT令牌。设置为响应标头,然后重定向到/
  • 浏览器加载/。 AngularJS在响应标头中识别JWT令牌,并将其存储在localStorage中
  • 所有后续调用的标头中均带有Bearer令牌(通过httpInterceptor注入)

注意:无状态会话

2。 OAuth2身份验证

  • 用户访问权限/
  • Springboot标识为受保护资源,并将用户重定向到/ login
  • / login被Spring安全性拦截。重定向到具有生成状态的Oauth2授权服务器,并将URL重定向回应用程序
  • 用户输入凭据
  • Oauth服务器重定向回应用程序URL“ / login?code = xxx&state = yyy”
  • / login被Spring安全性拦截。识别代码和状态,生成Cookie并在响应标头中设置。重定向到/
  • 浏览器加载/。浏览器在响应标头中识别cookie并将其存储。
  • 如果对/ user进行了调用,则Principal对象将使用JWT填充,我可以按如下方式提取
@RequestMapping(value= {"/user")
public ResponseEntity<Map<String, String>> user(Principal principal) throws Exception {
    OAuth2Authentication obj = (OAuth2Authentication) principal;
    authentication = obj.getUserAuthentication();
    OAuth2AuthenticationDetails oAuth2AuthenticationDetails = (OAuth2AuthenticationDetails) obj.getDetails();
    String jwt = oAuth2AuthenticationDetails.getTokenValue();
  • 所有后续调用将在请求中包含Cookie

注意:在服务器端创建了一个有状态会话来存储会话详细信息。这需要解密cookie并识别用户

现在,我想使用Oauth2 + JWT来实现安全性,但同时实现如下所示的无状态

3。 OAuth2 + JWT +无状态

  • 用户访问权限/
  • Springboot标识为受保护资源,并将用户重定向到/ login
  • / login被Spring安全性拦截。重定向到具有生成状态的Oauth2授权服务器,并将URL重定向回应用程序
  • 用户输入凭据
  • Oauth服务器重定向回应用程序URL“ / login?code = xxx&state = yyy”
  
      
  • / login被Spring安全性拦截。识别代码和状态,通过调用提取JWT令牌   OAuth2AuthenticationDetails.getTokenValue()并进行响应设置   标头。重定向到/
  •   
  • 浏览器加载/。 AngularJS在响应标头中识别JWT令牌,并将其存储在localStorage中
  • 所有后续调用的标头中均带有Bearer令牌(通过httpInterceptor注入)

问题

我正在尝试弄清楚如何执行上面突出显示的步骤

2 个答案:

答案 0 :(得分:0)

如果我正确的话,只是一个想法/方向: 您可以创建一个GenericFilterBean并将其添加到HttpSecurity筛选器链。

使用JWT时,应该有类似的东西(一个过滤器,该过滤器从标头中提取不记名令牌),然后为Spring Security填充一个Authentication对象。

因此新的过滤器可以从请求中获取令牌并相应地设置响应。 您还可以在不受保护的(!)回调终结点(例如login/callback?...)中处理该问题,然后为您设置cookie。

在我们的应用程序中,服务器(春季启动)完全是无状态的,没有任何oauth或有状态的东西。显然,对于AngularJS(以及/下的一些REST-API),它从来没有重定向任何东西或具有/api/...之外的任何其他视图/端点。因此,OAuth-flow完全由AngularJS处理,后者依次检查来自oauth-server的回调并在本地设置JWT-Token(就像您的第一种方法一样)。在第一个版本中,我们还尝试将重定向与无状态的JWT和有状态的会话等混合使用,但这导致登录时出现非常奇怪的行为-状态(登录或不登录)并不总是很清楚,在某些情况下重定向是错误的,等等。

答案 1 :(得分:0)

This 可能会帮助您实施所需的解决方案。

作者建议,一旦用户成功通过 Oauth2 提供商(Google 等)的身份验证,您将一个短期令牌作为 URL 参数发送到您的前端应用程序,并使用此短期令牌将其交换为一个长期存在的令牌令牌。