将经过身份验证的用户保存到来自 Azure AD 的数据库

Ale*_*dar 6 java azure oauth-2.0 jwt angular

我正在开发一个简单的 Web 应用程序,用于学习目的,使用 Angular 作为前端,使用 Java Spring 作为后端。我没有需要你们帮助我解决的特定问题,相反,我有一个关于 OAuth2 身份验证的问题。

我已在 Azure AD 中注册了我的 Angular SPA(授权代码流 + PKCE),我设置了角色,一切正常。我的问题是,当经过身份验证的用户 ping 我的后端时,我该怎么办?我的后端没有有关用户的信息。

我想到了一个解决方案,制作一个网络过滤器,每次经过身份验证的用户 ping 任何需要用户进行身份验证的端点时,检查数据库是否该用户存在(通过用户名),如果不存在则保存他。我很确定这会起作用,但我不认为这是最好的解决方案,考虑到我的 Web 过滤器必须从数据库中读取每个传入的 HTTP 请求,并偶尔写入数据库(如果用户首次登录)。

我不应该担心性能问题,因为我只是为了学习目的而构建它,但尽管如此,我还是想以正确的方式做到这一点。我尝试以多种方式进行谷歌搜索,但我想我没有使用正确的关键字来找到我要找的东西。任何意见或建议将不胜感激!谢谢!

编辑:我按照这篇文章实现了 OAuth2 + OIDC 身份验证和授权,我在后端的安全配置是相同的: https: //ordina-jworks.github.io/security/2020/08/18/Securing-Applications- Azure-AD.html

Nag*_*tri 2

发布清晰的需求讨论。如果你想使用有以下内容:

  • 接受 Azure AD 登录用户来使用您的 Web 服务
  • 您需要以最小的网络延迟检查用户是否存在于您的应用程序数据库中。

由于要求不总是访问数据库,一种选择是使用缓存。

该缓存工作的理想解决方案是:

  • 确保使用 Web 过滤器检查每个 HTTP 请求的缓存
  • 确保缓存始终更新为通过 Azure AD 登录的最新用户

例子:

实施一个CacheService.java

package com.example.springboot;

import java.util.Collections;

import org.apache.catalina.User;
import org.springframework.cache.CacheManager;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.cache.concurrent.ConcurrentMapCache;
import org.springframework.cache.support.SimpleCacheManager;
import org.springframework.context.annotation.Bean;
import org.springframework.stereotype.Component;

@Component
public class CacheService {

  @Bean
  public CacheManager cacheManager() {
    SimpleCacheManager cacheManager = new SimpleCacheManager();
    cacheManager.setCaches(Collections.singletonList(new ConcurrentMapCache("users")));
    return cacheManager;
  }


  @Cacheable(cacheNames = "users")
  public User getUser(String username) {
    // Code below will not execute after the first calling for the given username. 
    // So if one username is already cached, it would not invoke for the same user again from the DB.

    // Get or Create a new user based on the Database call
    return null;
  }
}
Run Code Online (Sandbox Code Playgroud)

然后实现一个网络过滤器,例如:

package com.example.springboot;

import java.io.IOException;

import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.web.filter.GenericFilterBean;

@Component
public class CredentialsInjectionFilter extends GenericFilterBean {

  @Autowired
  private CacheService cacheService;

  @Override
  public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse,
      FilterChain filterChain) throws IOException, ServletException {

    cacheService.getUser("my_username");

    filterChain.doFilter(servletRequest, servletResponse);
  }
}
Run Code Online (Sandbox Code Playgroud)

有关使用 Springboot 进行缓存的更多信息:https://www.javadevjournal.com/spring/spring-caching/