This question is derived from reading Hadoop credential management: In Hadoop 3.3+, function UserGroupInformation.doAs can introduce an "execution scope", that allows some context information to be modified when being called inside the scope:
import org.apache.hadoop.security.UserGroupInformation
import java.security.PrivilegedAction
val ugi = UserGroupInformation.createUserForTesting("abc", Array("a", "b", "c"))
val u = UserGroupInformation.getCurrentUser
println(u)
val t1 = Thread.currentThread()
val t2 = ugi.doAs {
new PrivilegedAction[Thread] {
override def run(): Thread = {
val u = UserGroupInformation.getCurrentUser // alternatively, calling it in subroutine won't change its outcome
println(u)
val t = Thread.currentThread()
t
}
}
}
assert(t1 == t2)
/*
execution result:
os-user (auth:SIMPLE)
abc (auth:SIMPLE)
*/
It minimally depends on Java Security, which appears to implement a call-stack based approach and is agnostic to local thread, fibre, or coroutine, as implied in the following Java security implementation:
public static AccessControlContext getContext()
{
AccessControlContext acc = getStackAccessControlContext();
if (acc == null) {
// all we had was privileged system code. We don't want
// to return null though, so we construct a real ACC.
return new AccessControlContext(null, true);
} else {
return acc.optimize();
}
}
For scoped context information control, this appears to be the most lightweight approach I have seen in any JVM libraries: the underlying function can use any subroutine, without relying on boilerplate function parameter, macro or auto-completion like in alternative implementations (e.g. https://docs.scala-lang.org/scala3/book/ca-contextual-abstractions-intro.html).
My question is: Had this approach be used to control other context information? If not, why is it only reserved for Java security?