Keycloak和Spring Boot Rest API-用户特定的数据策略 [英] Keycloak and spring boot rest api - user specific data stragegy

查看:160
本文介绍了Keycloak和Spring Boot Rest API-用户特定的数据策略的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

Keycloak是一个用户联合身份解决方案,它与其他引用它的系统(例如,用于授权)独立(独立)运行,该系统具有自己的数据库.

Keycloak is a user federated identity solution running seperately (standalone) from other systems referencing to it (for authorization for example) having its own database.

问题: 我如何在我的REST API数据库中引用/创建用户特定的数据? 如何在其余api数据库中引用用户以获取特定于用户的数据?

Question: How would I reference / create user specific data in my rest api database? How would I reference the user in the rest api database to have user specific data?

想想像Post这样的表

Think of an table like Post

标题, 日期, 内容, 作者(这里是对用户的引用)

title, date, content, author (here would be the reference to the user)

推荐答案

在Java EE应用程序中,我们也有类似的要求,在该应用程序中,用户可以通过JSF网站创建数据.数据与审核信息(用户名,用户ID,时间戳等)一起存储到了postrgesql中,我想正是您想要实现的.

We have a similar requirement in a Java EE application, where a user can create data via a JSF website. Data is stored to postrgesql with audit information (username, userid, timestamps,...) so exactly what you want to achieve I suppose.

我们通过简单地通过会话中当前可用的访问令牌检索信息来实现.我们还在keycloak本身中引入了一个新的用户属性,它是一个自定义帐户ID.用户在密钥斗篷GUI上进行设置,然后我们通过accessToken.getOtherClaims().get("ACCOUNT_ID")对其进行检索,以查询特定于用户的数据.

We have implemented by simply retrieving the information via the access token that is currently available in the session. We also introduced a new user attribute in keycloak itself, which is a custom account id. The user sets it on keycloak GUI and we retrieve it via accessToken.getOtherClaims().get("ACCOUNT_ID") to query user specific data.

令牌本身是在过滤器中处理的,并在另一个bean中用于检索看起来像这样的数据

The token itself is handled in a filter and used in another bean to retrieve the data which looks like

@WebFilter(value = "/*")
public class RefreshTokenFilter implements Filter {

  @Inject
  private ServletOAuthClient oauthClient;

  @Inject
  private UserData userData;
  @Context
  KeycloakSecurityContext  sc;

  @Override
  public void init(FilterConfig filterConfig) throws ServletException {
  }

  @Override
  public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
    HttpServletRequest request = (HttpServletRequest) servletRequest;
    HttpServletResponse response = (HttpServletResponse) servletResponse;
    if (request.getUserPrincipal() != null) {
      KeycloakSecurityContext keycloakSecurityContext = ((KeycloakPrincipal) request.getUserPrincipal()).getKeycloakSecurityContext();
      userData.setAccessToken(keycloakSecurityContext.getToken());
      userData.setIdToken(keycloakSecurityContext.getIdToken());
    }
    filterChain.doFilter(request, response);
  }

  @Override
  public void destroy() {
  }
}

这里有处理数据访问的bean

and here I have the bean that handles the data access

@SessionScoped
@Named("userData")
public class UserData implements Serializable {

  private static final String ACCOUNT_ID = "accountId";
  private AccessToken accessToken;
  private IDToken idToken;

  public String getUserFullName() {
    return isHasAccessToken() ? accessToken.getName() : null;
  }

  public String getUserName() {
    return isHasAccessToken() ? accessToken.getPreferredUsername() : null;
  }

  public String getUserId() {
    return isHasAccessToken() ? accessToken.getSubject() : null;
  }

  public String getRoles() {
    StringBuilder roles = new StringBuilder();
    if (isHasAccessToken()) {
      accessToken.getRealmAccess().getRoles().stream().forEach(s -> roles.append(s).append(" "));
    }
    return roles.toString();
  }

  public boolean hasApplicationRole(String role) {
    return accessToken.getRealmAccess().isUserInRole(role);
  }

  public boolean isHasAccessToken() {
    return accessToken != null;
  }

  public List<String> getAccountIds() {
    return isHasAccessToken() && accessToken.getOtherClaims().get(ACCOUNT_ID)!=null ? (List<String>) accessToken.getOtherClaims().get(ACCOUNT_ID) : new ArrayList<>();
  }

  public void setAccessToken(AccessToken accessToken) {
    this.accessToken = accessToken;
  }

  public void setIdToken(IDToken idToken) {
    this.idToken = idToken;
  }
}

我认为Spring Boot会为您提供类似的选项来处理KeycloakSecurityContext.

I would assume spring boot will give you similar options to deal with the KeycloakSecurityContext.

这篇关于Keycloak和Spring Boot Rest API-用户特定的数据策略的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆