美文网首页
Flowable用户授权

Flowable用户授权

作者: NewBornCyanide | 来源:发表于2021-08-27 15:08 被阅读0次

目的

需要在Flowable框架下实现获取当前授权用户ID以及实现接口访问授权,由于Flowable是基于spring security的,考虑基于此实现。spring security原生的授权过程为:

1.构造token 
UsernamePasswordAuthenticationToken authReq = new UsernamePasswordAuthenticationToken(uid, pwd);
2.构造auth(继承了principal)
org.springframework.security.core.Authentication auth = authManager.authenticate(authReq);
3.向context传入auth对象
 SecurityContext sc = SecurityContextHolder.getContext();
 sc.setAuthentication(auth);

Flowable设置授权用户的方法为

Authentication.setAuthenticationContext(sc);
Authentication.setAuthenticatedUserId();
-------以下是源代码
public static void setAuthenticationContext(AuthenticationContext authenticationContext) {
        Authentication.authenticationContext = authenticationContext;
    }

需要将二者结合并尽可能复用代码。

源代码分析

在setAuthenticatedUserId方法中,会先向context设置principal,一般来说就是直接new一个UserIdPrincipal喂给context的setprincipal方法,而这个setprincipal的过程就是封装了spring security的context操作,

public static void setAuthenticatedUserId(String authenticatedUserId) {
        authenticationContext.setPrincipal(authenticatedUserId == null ? null : new UserIdPrincipal(authenticatedUserId));
    }
public void setPrincipal(Principal principal) {
        if (principal == null) {
            SecurityContextHolder.getContext().setAuthentication((Authentication)null);
        } else if (principal instanceof Authentication) {
            SecurityContextHolder.getContext().setAuthentication((Authentication)principal);
        } else {
            SecurityContextHolder.getContext().setAuthentication(new UsernamePasswordAuthenticationToken(principal, (Object)null));
            LOGGER.debug("Setting a principal that is not of type `org.springframework.security.core.Authentication`. When using Spring Security you can just set the user through 'SecurityContextHolder.getContext().setAuthentication(..)' Using 'org.springframework.security.authentication.UsernamePasswordAuthenticationToken' to wrap the principal of type '{}'", principal.getClass());
        }
    }

第一节的使用方法是走第二个分支。
这里可以发现,Flowable没有对用户进行授权的关键在于,setAuthentication方法所传入的principal没有认证信息,因此考虑外部手动构建context并投喂给正确的principal

最终代码如下:

 UsernamePasswordAuthenticationToken authReq = new UsernamePasswordAuthenticationToken(uid, pwd);
            org.springframework.security.core.Authentication auth = authManager.authenticate(authReq);
            SpringSecurityAuthenticationContext sc = new SpringSecurityAuthenticationContext();
            sc.setPrincipal(auth);
            Authentication.setAuthenticationContext(sc);

Flowable可以接收两种context:UserIdAuthenticationContext与SpringSecurityAuthenticationContext,这里应当使用后者

public class UserIdAuthenticationContext implements AuthenticationContext {
    private static ThreadLocal<Principal> authenticatedUserIdThreadLocal = new ThreadLocal();
---------------------------------------
final class ThreadLocalSecurityContextHolderStrategy implements SecurityContextHolderStrategy {
    private static final ThreadLocal<SecurityContext> contextHolder = new ThreadLocal();

虽然二者都基于threadlocal,但对比二者的底层实现可知后者才是单例模式

相关文章

网友评论

      本文标题:Flowable用户授权

      本文链接:https://www.haomeiwen.com/subject/ieymiltx.html