8267108: Alternate Subject.getSubject and doAs APIs that do not depend on Security Manager APIs
Reviewed-by: mullan
This commit is contained in:
parent
ce3ed65ac3
commit
a5c160c711
@ -27,18 +27,18 @@ package javax.security.auth;
|
||||
|
||||
import java.util.*;
|
||||
import java.io.*;
|
||||
import java.lang.reflect.*;
|
||||
import java.text.MessageFormat;
|
||||
import java.security.AccessController;
|
||||
import java.security.AccessControlContext;
|
||||
import java.security.DomainCombiner;
|
||||
import java.security.Permission;
|
||||
import java.security.PermissionCollection;
|
||||
import java.security.Principal;
|
||||
import java.security.PrivilegedAction;
|
||||
import java.security.PrivilegedExceptionAction;
|
||||
import java.security.PrivilegedActionException;
|
||||
import java.security.ProtectionDomain;
|
||||
import java.util.concurrent.Callable;
|
||||
import java.util.concurrent.CompletionException;
|
||||
|
||||
import sun.security.action.GetBooleanAction;
|
||||
import sun.security.util.ResourcesMgr;
|
||||
|
||||
/**
|
||||
@ -289,9 +289,10 @@ public final class Subject implements java.io.Serializable {
|
||||
* @deprecated This method depends on {@link AccessControlContext}
|
||||
* which, in conjunction with
|
||||
* {@linkplain SecurityManager the Security Manager}, is deprecated
|
||||
* and subject to removal in a future release. However, obtaining a
|
||||
* Subject is useful independent of the Security Manager, so a
|
||||
* replacement for this method may be added in a future release.
|
||||
* and subject to removal in a future release. However,
|
||||
* obtaining a Subject is useful independent of the Security Manager.
|
||||
* Thus, a replacement API named {@link #current()} has been added
|
||||
* which can be used to obtain the current subject.
|
||||
*/
|
||||
@SuppressWarnings("removal")
|
||||
@Deprecated(since="17", forRemoval=true)
|
||||
@ -319,6 +320,112 @@ public final class Subject implements java.io.Serializable {
|
||||
});
|
||||
}
|
||||
|
||||
// Store the current subject in a ThreadLocal when a system property is set.
|
||||
private static final boolean USE_TL = GetBooleanAction
|
||||
.privilegedGetProperty("jdk.security.auth.subject.useTL");
|
||||
|
||||
private static final InheritableThreadLocal<Subject> SUBJECT_THREAD_LOCAL =
|
||||
USE_TL ?
|
||||
new InheritableThreadLocal<>() {
|
||||
@Override protected Subject initialValue() {
|
||||
return null;
|
||||
}
|
||||
} : null;
|
||||
|
||||
/**
|
||||
* Returns the current subject.
|
||||
* <p>
|
||||
* The current subject is installed by the {@link #callAs} method.
|
||||
* When {@code callAs(subject, action)} is called, {@code action} is
|
||||
* executed with {@code subject} as its current subject which can be
|
||||
* retrieved by this method. After {@code action} is finished, the current
|
||||
* subject is reset to its previous value. The current
|
||||
* subject is {@code null} before the first call of {@code callAs()}.
|
||||
* <p>
|
||||
* When a new thread is created, its current subject is the same as
|
||||
* the one of its parent thread, and will not change even if
|
||||
* its parent thread's current subject is changed to another value.
|
||||
*
|
||||
* @implNote
|
||||
* By default, this method returns the same value as
|
||||
* {@code Subject.getSubject(AccessController.getContext())}. This
|
||||
* preserves compatibility with code that may still be calling {@code doAs}
|
||||
* which installs the subject in an {@code AccessControlContext}. However,
|
||||
* if the system property {@systemProperty jdk.security.auth.subject.useTL}
|
||||
* is set to {@code true}, the subject is retrieved from an inheritable
|
||||
* {@code ThreadLocal} object. This behavior is subject to
|
||||
* change in a future version.
|
||||
*
|
||||
* @return the current subject, or {@code null} if a current subject is
|
||||
* not installed or the current subject is set to {@code null}.
|
||||
* @see #callAs(Subject, Callable)
|
||||
* @since 18
|
||||
*/
|
||||
@SuppressWarnings("removal")
|
||||
public static Subject current() {
|
||||
return USE_TL
|
||||
? SUBJECT_THREAD_LOCAL.get()
|
||||
: getSubject(AccessController.getContext());
|
||||
}
|
||||
|
||||
/**
|
||||
* Executes a {@code Callable} with {@code subject} as the
|
||||
* current subject.
|
||||
*
|
||||
* @implNote
|
||||
* By default, this method calls {@link #doAs(Subject, PrivilegedExceptionAction)
|
||||
* Subject.doAs(subject, altAction)} which stores the subject in
|
||||
* a new {@code AccessControlContext}, where {@code altAction.run()}
|
||||
* is equivalent to {@code action.call()} and the exception thrown is
|
||||
* modified to match the specification of this method. This preserves
|
||||
* compatibility with code that may still be calling
|
||||
* {@code getSubject(AccessControlContext)} which retrieves the subject
|
||||
* from an {@code AccessControlContext}. However,
|
||||
* if the system property {@code jdk.security.auth.subject.useTL}
|
||||
* is set to {@code true}, the current subject will be stored in an inheritable
|
||||
* {@code ThreadLocal} object. This behavior is subject to change in a
|
||||
* future version.
|
||||
*
|
||||
* @param subject the {@code Subject} that the specified {@code action}
|
||||
* will run as. This parameter may be {@code null}.
|
||||
* @param action the code to be run with {@code subject} as its current
|
||||
* subject. Must not be {@code null}.
|
||||
* @param <T> the type of value returned by the {@code call} method
|
||||
* of {@code action}
|
||||
* @return the value returned by the {@code call} method of {@code action}
|
||||
* @throws NullPointerException if {@code action} is {@code null}
|
||||
* @throws CompletionException if {@code action.call()} throws an exception.
|
||||
* The cause of the {@code CompletionException} is set to the exception
|
||||
* thrown by {@code action.call()}.
|
||||
* @see #current()
|
||||
* @since 18
|
||||
*/
|
||||
public static <T> T callAs(final Subject subject,
|
||||
final Callable<T> action) throws CompletionException {
|
||||
if (USE_TL) {
|
||||
Subject oldSubject = SUBJECT_THREAD_LOCAL.get();
|
||||
SUBJECT_THREAD_LOCAL.set(subject);
|
||||
try {
|
||||
return action.call();
|
||||
} catch (Exception e) {
|
||||
throw new CompletionException(e);
|
||||
} finally {
|
||||
SUBJECT_THREAD_LOCAL.set(oldSubject);
|
||||
}
|
||||
} else {
|
||||
try {
|
||||
PrivilegedExceptionAction<T> pa = () -> action.call();
|
||||
@SuppressWarnings("removal")
|
||||
var result = doAs(subject, pa);
|
||||
return result;
|
||||
} catch (PrivilegedActionException e) {
|
||||
throw new CompletionException(e.getCause());
|
||||
} catch (Exception e) {
|
||||
throw new CompletionException(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Perform work as a particular {@code Subject}.
|
||||
*
|
||||
@ -354,8 +461,17 @@ public final class Subject implements java.io.Serializable {
|
||||
* {@link AuthPermission#AuthPermission(String)
|
||||
* AuthPermission("doAs")} permission to invoke this
|
||||
* method.
|
||||
*
|
||||
* @deprecated This method depends on {@link AccessControlContext}
|
||||
* which, in conjunction with
|
||||
* {@linkplain SecurityManager the Security Manager}, is deprecated
|
||||
* and subject to removal in a future release. However, performing
|
||||
* work as a Subject is useful independent of the Security Manager.
|
||||
* Thus, a replacement API named {@link #callAs} has been added
|
||||
* which can be used to perform the same work.
|
||||
*/
|
||||
@SuppressWarnings("removal")
|
||||
@Deprecated(since="18", forRemoval=true)
|
||||
public static <T> T doAs(final Subject subject,
|
||||
final java.security.PrivilegedAction<T> action) {
|
||||
|
||||
@ -417,8 +533,17 @@ public final class Subject implements java.io.Serializable {
|
||||
* {@link AuthPermission#AuthPermission(String)
|
||||
* AuthPermission("doAs")} permission to invoke this
|
||||
* method.
|
||||
*
|
||||
* @deprecated This method depends on {@link AccessControlContext}
|
||||
* which, in conjunction with
|
||||
* {@linkplain SecurityManager the Security Manager}, is deprecated
|
||||
* and subject to removal in a future release. However, performing
|
||||
* work as a Subject is useful independent of the Security Manager.
|
||||
* Thus, a replacement API named {@link #callAs} has been added
|
||||
* which can be used to perform the same work.
|
||||
*/
|
||||
@SuppressWarnings("removal")
|
||||
@Deprecated(since="18", forRemoval=true)
|
||||
public static <T> T doAs(final Subject subject,
|
||||
final java.security.PrivilegedExceptionAction<T> action)
|
||||
throws java.security.PrivilegedActionException {
|
||||
@ -857,10 +982,7 @@ public final class Subject implements java.io.Serializable {
|
||||
// avoid deadlock from dual locks
|
||||
thatPrivCredentials = new HashSet<>(that.privCredentials);
|
||||
}
|
||||
if (!privCredentials.equals(thatPrivCredentials)) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
return privCredentials.equals(thatPrivCredentials);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
@ -933,7 +1055,7 @@ public final class Subject implements java.io.Serializable {
|
||||
@Override
|
||||
public int hashCode() {
|
||||
|
||||
/**
|
||||
/*
|
||||
* The hashcode is derived exclusive or-ing the
|
||||
* hashcodes of this Subject's Principals and credentials.
|
||||
*
|
||||
@ -1244,7 +1366,7 @@ public final class Subject implements java.io.Serializable {
|
||||
} else {
|
||||
|
||||
// For private credentials:
|
||||
// If the caller does not have read permission for
|
||||
// If the caller does not have read permission
|
||||
// for o.getClass(), we throw a SecurityException.
|
||||
// Otherwise we check the private cred set to see whether
|
||||
// it contains the Object
|
||||
@ -1316,7 +1438,7 @@ public final class Subject implements java.io.Serializable {
|
||||
c = collectionNullClean(c);
|
||||
|
||||
for (Object item : c) {
|
||||
if (this.contains(item) == false) {
|
||||
if (!this.contains(item)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@ -1534,7 +1656,7 @@ public final class Subject implements java.io.Serializable {
|
||||
break;
|
||||
}
|
||||
|
||||
// Check whether the caller has permisson to get
|
||||
// Check whether the caller has permission to get
|
||||
// credentials of Class c
|
||||
|
||||
while (iterator.hasNext()) {
|
||||
|
@ -40,7 +40,6 @@ import java.util.HashSet;
|
||||
import java.util.Vector;
|
||||
import java.util.Iterator;
|
||||
import java.security.AccessController;
|
||||
import java.security.AccessControlContext;
|
||||
import java.security.PrivilegedExceptionAction;
|
||||
import java.security.PrivilegedActionException;
|
||||
import javax.security.auth.callback.CallbackHandler;
|
||||
@ -313,20 +312,18 @@ public class GSSUtil {
|
||||
(initiate? " INIT" : " ACCEPT") + " cred (" +
|
||||
(name == null? "<<DEF>>" : name.toString()) + ", " +
|
||||
credCls.getName() + ")");
|
||||
@SuppressWarnings("removal")
|
||||
final AccessControlContext acc = AccessController.getContext();
|
||||
try {
|
||||
@SuppressWarnings("removal")
|
||||
Vector<T> creds =
|
||||
AccessController.doPrivileged
|
||||
AccessController.doPrivilegedWithCombiner
|
||||
(new PrivilegedExceptionAction<Vector<T>>() {
|
||||
public Vector<T> run() throws Exception {
|
||||
Subject accSubj = Subject.getSubject(acc);
|
||||
Subject currSubj = Subject.current();
|
||||
Vector<T> result = null;
|
||||
if (accSubj != null) {
|
||||
if (currSubj != null) {
|
||||
result = new Vector<T>();
|
||||
Iterator<GSSCredentialImpl> iterator =
|
||||
accSubj.getPrivateCredentials
|
||||
currSubj.getPrivateCredentials
|
||||
(GSSCredentialImpl.class).iterator();
|
||||
while (iterator.hasNext()) {
|
||||
GSSCredentialImpl cred = iterator.next();
|
||||
|
@ -25,7 +25,6 @@
|
||||
|
||||
package sun.security.jgss.krb5;
|
||||
|
||||
import java.io.IOException;
|
||||
import org.ietf.jgss.*;
|
||||
import sun.security.jgss.GSSCaller;
|
||||
import sun.security.jgss.spi.*;
|
||||
@ -33,7 +32,6 @@ import sun.security.krb5.*;
|
||||
import java.security.PrivilegedActionException;
|
||||
import java.security.PrivilegedExceptionAction;
|
||||
import java.security.AccessController;
|
||||
import java.security.AccessControlContext;
|
||||
import javax.security.auth.DestroyFailedException;
|
||||
|
||||
/**
|
||||
@ -65,16 +63,15 @@ public class Krb5AcceptCredential
|
||||
|
||||
final String serverPrinc = (name == null? null:
|
||||
name.getKrb5PrincipalName().getName());
|
||||
final AccessControlContext acc = AccessController.getContext();
|
||||
|
||||
ServiceCreds creds = null;
|
||||
try {
|
||||
creds = AccessController.doPrivileged(
|
||||
creds = AccessController.doPrivilegedWithCombiner(
|
||||
new PrivilegedExceptionAction<ServiceCreds>() {
|
||||
public ServiceCreds run() throws Exception {
|
||||
return Krb5Util.getServiceCreds(
|
||||
caller == GSSCaller.CALLER_UNKNOWN ? GSSCaller.CALLER_ACCEPT: caller,
|
||||
serverPrinc, acc);
|
||||
serverPrinc);
|
||||
}});
|
||||
} catch (PrivilegedActionException e) {
|
||||
GSSException ge =
|
||||
|
@ -37,7 +37,6 @@ import java.io.OutputStream;
|
||||
import java.io.IOException;
|
||||
import java.security.Provider;
|
||||
import java.security.AccessController;
|
||||
import java.security.AccessControlContext;
|
||||
import java.security.Key;
|
||||
import java.security.PrivilegedActionException;
|
||||
import java.security.PrivilegedExceptionAction;
|
||||
@ -641,16 +640,12 @@ class Krb5Context implements GSSContextSpi {
|
||||
* for this service in the Subject and reuse it
|
||||
*/
|
||||
|
||||
@SuppressWarnings("removal")
|
||||
final AccessControlContext acc =
|
||||
AccessController.getContext();
|
||||
|
||||
if (GSSUtil.useSubjectCredsOnly(caller)) {
|
||||
KerberosTicket kerbTicket = null;
|
||||
try {
|
||||
// get service ticket from caller's subject
|
||||
@SuppressWarnings("removal")
|
||||
var tmp = AccessController.doPrivileged(
|
||||
var tmp = AccessController.doPrivilegedWithCombiner(
|
||||
new PrivilegedExceptionAction<KerberosTicket>() {
|
||||
public KerberosTicket run() throws Exception {
|
||||
// XXX to be cleaned
|
||||
@ -665,8 +660,7 @@ class Krb5Context implements GSSContextSpi {
|
||||
second == null ?
|
||||
myName.getKrb5PrincipalName().getName():
|
||||
second.getName().getKrb5PrincipalName().getName(),
|
||||
peerName.getKrb5PrincipalName().getName(),
|
||||
acc);
|
||||
peerName.getKrb5PrincipalName().getName());
|
||||
}});
|
||||
kerbTicket = tmp;
|
||||
} catch (PrivilegedActionException e) {
|
||||
@ -710,10 +704,10 @@ class Krb5Context implements GSSContextSpi {
|
||||
if (GSSUtil.useSubjectCredsOnly(caller)) {
|
||||
@SuppressWarnings("removal")
|
||||
final Subject subject =
|
||||
AccessController.doPrivileged(
|
||||
AccessController.doPrivilegedWithCombiner(
|
||||
new java.security.PrivilegedAction<Subject>() {
|
||||
public Subject run() {
|
||||
return (Subject.getSubject(acc));
|
||||
return (Subject.current());
|
||||
}
|
||||
});
|
||||
if (subject != null &&
|
||||
|
@ -35,7 +35,6 @@ import java.net.InetAddress;
|
||||
import java.io.IOException;
|
||||
import java.util.Date;
|
||||
import java.security.AccessController;
|
||||
import java.security.AccessControlContext;
|
||||
import java.security.PrivilegedExceptionAction;
|
||||
import java.security.PrivilegedActionException;
|
||||
|
||||
@ -365,20 +364,17 @@ public class Krb5InitCredential
|
||||
clientPrincipal = null;
|
||||
}
|
||||
|
||||
final AccessControlContext acc = AccessController.getContext();
|
||||
|
||||
try {
|
||||
final GSSCaller realCaller = (caller == GSSCaller.CALLER_UNKNOWN)
|
||||
? GSSCaller.CALLER_INITIATE
|
||||
: caller;
|
||||
return AccessController.doPrivileged(
|
||||
return AccessController.doPrivilegedWithCombiner(
|
||||
new PrivilegedExceptionAction<KerberosTicket>() {
|
||||
public KerberosTicket run() throws Exception {
|
||||
// It's OK to use null as serverPrincipal. TGT is almost
|
||||
// the first ticket for a principal and we use list.
|
||||
return Krb5Util.getInitialTicket(
|
||||
realCaller,
|
||||
clientPrincipal, acc);
|
||||
realCaller, clientPrincipal);
|
||||
}});
|
||||
} catch (PrivilegedActionException e) {
|
||||
GSSException ge =
|
||||
|
@ -30,7 +30,6 @@ import javax.security.auth.kerberos.KerberosPrincipal;
|
||||
import javax.security.auth.kerberos.KeyTab;
|
||||
import javax.security.auth.Subject;
|
||||
import javax.security.auth.login.LoginException;
|
||||
import java.security.AccessControlContext;
|
||||
|
||||
import sun.security.action.GetBooleanAction;
|
||||
import sun.security.jgss.GSSUtil;
|
||||
@ -62,14 +61,12 @@ public class Krb5Util {
|
||||
* pair from the Subject in the specified AccessControlContext.
|
||||
*/
|
||||
static KerberosTicket getServiceTicket(GSSCaller caller,
|
||||
String clientPrincipal, String serverPrincipal,
|
||||
@SuppressWarnings("removal") AccessControlContext acc) throws LoginException {
|
||||
|
||||
// Try to get ticket from acc's Subject
|
||||
String clientPrincipal, String serverPrincipal) {
|
||||
// Try to get ticket from current Subject
|
||||
@SuppressWarnings("removal")
|
||||
Subject accSubj = Subject.getSubject(acc);
|
||||
Subject currSubj = Subject.current();
|
||||
KerberosTicket ticket =
|
||||
SubjectComber.find(accSubj, serverPrincipal, clientPrincipal,
|
||||
SubjectComber.find(currSubj, serverPrincipal, clientPrincipal,
|
||||
KerberosTicket.class);
|
||||
|
||||
return ticket;
|
||||
@ -83,14 +80,11 @@ public class Krb5Util {
|
||||
* a LoginContext.
|
||||
*/
|
||||
static KerberosTicket getInitialTicket(GSSCaller caller,
|
||||
String clientPrincipal,
|
||||
@SuppressWarnings("removal") AccessControlContext acc) throws LoginException {
|
||||
String clientPrincipal) throws LoginException {
|
||||
|
||||
// Try to get ticket from acc's Subject
|
||||
@SuppressWarnings("removal")
|
||||
Subject accSubj = Subject.getSubject(acc);
|
||||
Subject currSubj = Subject.current();
|
||||
KerberosTicket ticket =
|
||||
SubjectComber.find(accSubj, null, clientPrincipal,
|
||||
SubjectComber.find(currSubj, null, clientPrincipal,
|
||||
KerberosTicket.class);
|
||||
|
||||
// Try to get ticket from Subject obtained from GSSUtil
|
||||
@ -106,18 +100,14 @@ public class Krb5Util {
|
||||
* Retrieves the ServiceCreds for the specified server principal from
|
||||
* the Subject in the specified AccessControlContext. If not found, and if
|
||||
* useSubjectCredsOnly is false, then obtain from a LoginContext.
|
||||
*
|
||||
* NOTE: This method is also used by JSSE Kerberos Cipher Suites
|
||||
*/
|
||||
public static ServiceCreds getServiceCreds(GSSCaller caller,
|
||||
String serverPrincipal, @SuppressWarnings("removal") AccessControlContext acc)
|
||||
throws LoginException {
|
||||
String serverPrincipal) throws LoginException {
|
||||
|
||||
@SuppressWarnings("removal")
|
||||
Subject accSubj = Subject.getSubject(acc);
|
||||
Subject currSubj = Subject.current();
|
||||
ServiceCreds sc = null;
|
||||
if (accSubj != null) {
|
||||
sc = ServiceCreds.getInstance(accSubj, serverPrincipal);
|
||||
if (currSubj != null) {
|
||||
sc = ServiceCreds.getInstance(currSubj, serverPrincipal);
|
||||
}
|
||||
if (sc == null && !GSSUtil.useSubjectCredsOnly(caller)) {
|
||||
Subject subject = GSSUtil.login(caller, GSSUtil.GSS_KRB5_MECH_OID);
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2003, 2014, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2003, 2021, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -35,11 +35,11 @@
|
||||
|
||||
import javax.security.sasl.*;
|
||||
import javax.security.auth.callback.*;
|
||||
import java.security.*;
|
||||
import javax.security.auth.Subject;
|
||||
import javax.security.auth.login.*;
|
||||
import com.sun.security.auth.callback.*;
|
||||
import java.util.HashMap;
|
||||
import java.util.concurrent.Callable;
|
||||
|
||||
public class AuthOnly {
|
||||
private static final String MECH = "GSSAPI";
|
||||
@ -84,8 +84,8 @@ public class AuthOnly {
|
||||
srvprops.put(Sasl.QOP, "auth,auth-int,auth-conf");
|
||||
|
||||
final SaslClient clnt = (SaslClient)
|
||||
Subject.doAs(clntSubj, new PrivilegedExceptionAction() {
|
||||
public Object run() throws Exception {
|
||||
Subject.callAs(clntSubj, new Callable<>() {
|
||||
public Object call() throws Exception {
|
||||
return Sasl.createSaslClient(
|
||||
new String[]{MECH}, null, PROTOCOL, SERVER_FQDN,
|
||||
clntprops, null);
|
||||
@ -97,8 +97,8 @@ public class AuthOnly {
|
||||
System.out.println(srvSubj);
|
||||
}
|
||||
final SaslServer srv = (SaslServer)
|
||||
Subject.doAs(srvSubj, new PrivilegedExceptionAction() {
|
||||
public Object run() throws Exception {
|
||||
Subject.callAs(srvSubj, new Callable<Object>() {
|
||||
public Object call() throws Exception {
|
||||
return Sasl.createSaslServer(MECH, PROTOCOL, SERVER_FQDN,
|
||||
srvprops, srvCbh);
|
||||
}
|
||||
@ -117,27 +117,18 @@ public class AuthOnly {
|
||||
byte[] response;
|
||||
byte[] challenge;
|
||||
|
||||
response = (byte[]) Subject.doAs(clntSubj,
|
||||
new PrivilegedExceptionAction() {
|
||||
public Object run() throws Exception {
|
||||
return (clnt.hasInitialResponse()? clnt.evaluateChallenge(EMPTY) : EMPTY);
|
||||
}});
|
||||
response = (byte[]) Subject.callAs(clntSubj,
|
||||
() -> (clnt.hasInitialResponse()? clnt.evaluateChallenge(EMPTY) : EMPTY));
|
||||
|
||||
while (!clnt.isComplete() || !srv.isComplete()) {
|
||||
final byte[] responseCopy = response;
|
||||
challenge = (byte[]) Subject.doAs(srvSubj,
|
||||
new PrivilegedExceptionAction() {
|
||||
public Object run() throws Exception {
|
||||
return srv.evaluateResponse(responseCopy);
|
||||
}});
|
||||
challenge = (byte[]) Subject.callAs(srvSubj,
|
||||
() -> srv.evaluateResponse(responseCopy));
|
||||
|
||||
if (challenge != null) {
|
||||
final byte[] challengeCopy = challenge;
|
||||
response = (byte[]) Subject.doAs(clntSubj,
|
||||
new PrivilegedExceptionAction() {
|
||||
public Object run() throws Exception {
|
||||
return clnt.evaluateChallenge(challengeCopy);
|
||||
}});
|
||||
response = (byte[]) Subject.callAs(clntSubj,
|
||||
() -> clnt.evaluateChallenge(challengeCopy));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2004, 2014, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2004, 2021, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -36,7 +36,6 @@
|
||||
|
||||
import javax.security.sasl.*;
|
||||
import javax.security.auth.callback.*;
|
||||
import java.security.*;
|
||||
import javax.security.auth.Subject;
|
||||
import javax.security.auth.login.*;
|
||||
import com.sun.security.auth.callback.*;
|
||||
@ -85,25 +84,18 @@ public class ConfSecurityLayer {
|
||||
srvprops.put(Sasl.QOP, "auth,auth-int,auth-conf");
|
||||
|
||||
final SaslClient clnt = (SaslClient)
|
||||
Subject.doAs(clntSubj, new PrivilegedExceptionAction() {
|
||||
public Object run() throws Exception {
|
||||
return Sasl.createSaslClient(
|
||||
Subject.callAs(clntSubj, () ->Sasl.createSaslClient(
|
||||
new String[]{MECH}, null, PROTOCOL, SERVER_FQDN,
|
||||
clntprops, null);
|
||||
}
|
||||
});
|
||||
clntprops, null));
|
||||
|
||||
if (verbose) {
|
||||
System.out.println(clntSubj);
|
||||
System.out.println(srvSubj);
|
||||
}
|
||||
final SaslServer srv = (SaslServer)
|
||||
Subject.doAs(srvSubj, new PrivilegedExceptionAction() {
|
||||
public Object run() throws Exception {
|
||||
return Sasl.createSaslServer(MECH, PROTOCOL, SERVER_FQDN,
|
||||
srvprops, srvCbh);
|
||||
}
|
||||
});
|
||||
Subject.callAs(srvSubj, () ->
|
||||
Sasl.createSaslServer(MECH, PROTOCOL, SERVER_FQDN,
|
||||
srvprops, srvCbh));
|
||||
|
||||
|
||||
if (clnt == null) {
|
||||
@ -118,27 +110,18 @@ public class ConfSecurityLayer {
|
||||
byte[] response;
|
||||
byte[] challenge;
|
||||
|
||||
response = (byte[]) Subject.doAs(clntSubj,
|
||||
new PrivilegedExceptionAction() {
|
||||
public Object run() throws Exception {
|
||||
return (clnt.hasInitialResponse()? clnt.evaluateChallenge(EMPTY) : EMPTY);
|
||||
}});
|
||||
response = Subject.callAs(clntSubj,
|
||||
() -> (clnt.hasInitialResponse()? clnt.evaluateChallenge(EMPTY) : EMPTY));
|
||||
|
||||
while (!clnt.isComplete() || !srv.isComplete()) {
|
||||
final byte[] responseCopy = response;
|
||||
challenge = (byte[]) Subject.doAs(srvSubj,
|
||||
new PrivilegedExceptionAction() {
|
||||
public Object run() throws Exception {
|
||||
return srv.evaluateResponse(responseCopy);
|
||||
}});
|
||||
challenge = Subject.callAs(srvSubj,
|
||||
() -> srv.evaluateResponse(responseCopy));
|
||||
|
||||
if (challenge != null) {
|
||||
final byte[] challengeCopy = challenge;
|
||||
response = (byte[]) Subject.doAs(clntSubj,
|
||||
new PrivilegedExceptionAction() {
|
||||
public Object run() throws Exception {
|
||||
return clnt.evaluateChallenge(challengeCopy);
|
||||
}});
|
||||
response = Subject.callAs(clntSubj,
|
||||
() -> clnt.evaluateChallenge(challengeCopy));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2003, 2014, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2003, 2021, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -36,7 +36,6 @@
|
||||
|
||||
import javax.security.sasl.*;
|
||||
import javax.security.auth.callback.*;
|
||||
import java.security.*;
|
||||
import javax.security.auth.Subject;
|
||||
import javax.security.auth.login.*;
|
||||
import com.sun.security.auth.callback.*;
|
||||
@ -84,26 +83,20 @@ public class NoSecurityLayer {
|
||||
clntprops.put(Sasl.QOP, "auth");
|
||||
srvprops.put(Sasl.QOP, "auth,auth-int,auth-conf");
|
||||
|
||||
final SaslClient clnt = (SaslClient)
|
||||
Subject.doAs(clntSubj, new PrivilegedExceptionAction() {
|
||||
public Object run() throws Exception {
|
||||
return Sasl.createSaslClient(
|
||||
final SaslClient clnt =
|
||||
Subject.callAs(clntSubj, () ->
|
||||
Sasl.createSaslClient(
|
||||
new String[]{MECH}, null, PROTOCOL, SERVER_FQDN,
|
||||
clntprops, null);
|
||||
}
|
||||
});
|
||||
clntprops, null));
|
||||
|
||||
if (verbose) {
|
||||
System.out.println(clntSubj);
|
||||
System.out.println(srvSubj);
|
||||
}
|
||||
final SaslServer srv = (SaslServer)
|
||||
Subject.doAs(srvSubj, new PrivilegedExceptionAction() {
|
||||
public Object run() throws Exception {
|
||||
return Sasl.createSaslServer(MECH, PROTOCOL, SERVER_FQDN,
|
||||
srvprops, srvCbh);
|
||||
}
|
||||
});
|
||||
final SaslServer srv =
|
||||
Subject.callAs(srvSubj, () ->
|
||||
Sasl.createSaslServer(MECH, PROTOCOL, SERVER_FQDN,
|
||||
srvprops, srvCbh));
|
||||
|
||||
|
||||
if (clnt == null) {
|
||||
@ -118,27 +111,18 @@ public class NoSecurityLayer {
|
||||
byte[] response;
|
||||
byte[] challenge;
|
||||
|
||||
response = (byte[]) Subject.doAs(clntSubj,
|
||||
new PrivilegedExceptionAction() {
|
||||
public Object run() throws Exception {
|
||||
return (clnt.hasInitialResponse()? clnt.evaluateChallenge(EMPTY) : EMPTY);
|
||||
}});
|
||||
response = Subject.callAs(clntSubj,
|
||||
() -> (clnt.hasInitialResponse()? clnt.evaluateChallenge(EMPTY) : EMPTY));
|
||||
|
||||
while (!clnt.isComplete() || !srv.isComplete()) {
|
||||
final byte[] responseCopy = response;
|
||||
challenge = (byte[]) Subject.doAs(srvSubj,
|
||||
new PrivilegedExceptionAction() {
|
||||
public Object run() throws Exception {
|
||||
return srv.evaluateResponse(responseCopy);
|
||||
}});
|
||||
challenge = Subject.callAs(srvSubj,
|
||||
() -> srv.evaluateResponse(responseCopy));
|
||||
|
||||
if (challenge != null) {
|
||||
final byte[] challengeCopy = challenge;
|
||||
response = (byte[]) Subject.doAs(clntSubj,
|
||||
new PrivilegedExceptionAction() {
|
||||
public Object run() throws Exception {
|
||||
return clnt.evaluateChallenge(challengeCopy);
|
||||
}});
|
||||
response = Subject.callAs(clntSubj,
|
||||
() -> clnt.evaluateChallenge(challengeCopy));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2005, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2005, 2021, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -28,6 +28,7 @@
|
||||
*/
|
||||
|
||||
import java.security.*;
|
||||
import java.util.concurrent.Callable;
|
||||
import javax.security.auth.Subject;
|
||||
import javax.security.auth.x500.X500Principal;
|
||||
|
||||
@ -38,16 +39,15 @@ public class PreserveCombiner {
|
||||
Subject s = new Subject();
|
||||
s.getPrincipals().add(new X500Principal("cn=duke"));
|
||||
|
||||
String result = (String)Subject.doAs(s, new PrivilegedAction() {
|
||||
public Object run() {
|
||||
String result = Subject.callAs(s, new Callable<String>() {
|
||||
public String call() {
|
||||
|
||||
// get subject from current ACC - this always worked
|
||||
Subject doAsSubject =
|
||||
Subject.getSubject(AccessController.getContext());
|
||||
if (doAsSubject == null) {
|
||||
Subject callAsSubject = Subject.current();
|
||||
if (callAsSubject == null) {
|
||||
return "test 1 failed";
|
||||
} else {
|
||||
System.out.println(doAsSubject);
|
||||
System.out.println(callAsSubject);
|
||||
System.out.println("test 1 passed");
|
||||
}
|
||||
|
||||
@ -56,8 +56,7 @@ public class PreserveCombiner {
|
||||
(new PrivilegedAction<String>() {
|
||||
public String run() {
|
||||
// get subject after doPriv
|
||||
Subject doPrivSubject =
|
||||
Subject.getSubject(AccessController.getContext());
|
||||
Subject doPrivSubject = Subject.current();
|
||||
if (doPrivSubject == null) {
|
||||
return "test 2 failed";
|
||||
} else {
|
||||
@ -79,8 +78,7 @@ public class PreserveCombiner {
|
||||
(new PrivilegedExceptionAction<String>() {
|
||||
public String run() throws PrivilegedActionException {
|
||||
// get subject after doPriv
|
||||
Subject doPrivSubject = Subject.getSubject
|
||||
(AccessController.getContext());
|
||||
Subject doPrivSubject = Subject.current();
|
||||
if (doPrivSubject == null) {
|
||||
return "test 3 failed";
|
||||
} else {
|
||||
|
149
test/jdk/javax/security/auth/Subject/CurrentSubject.java
Normal file
149
test/jdk/javax/security/auth/Subject/CurrentSubject.java
Normal file
@ -0,0 +1,149 @@
|
||||
/*
|
||||
* Copyright (c) 2021, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
import javax.security.auth.Subject;
|
||||
import java.security.AccessController;
|
||||
import java.security.Principal;
|
||||
import java.security.PrivilegedAction;
|
||||
import java.util.concurrent.CountDownLatch;
|
||||
import java.util.concurrent.atomic.AtomicInteger;
|
||||
|
||||
/*
|
||||
* @test
|
||||
* @bug 8267108
|
||||
* @summary confirm current subject specification
|
||||
* @run main/othervm
|
||||
* -Djdk.security.auth.subject.useTL=false -Dtest=both CurrentSubject
|
||||
* @run main/othervm
|
||||
* -Djdk.security.auth.subject.useTL=true -Dtest=old CurrentSubject
|
||||
* @run main/othervm
|
||||
* -Djdk.security.auth.subject.useTL=true -Dtest=new CurrentSubject
|
||||
*/
|
||||
public class CurrentSubject {
|
||||
|
||||
static final boolean TEST_NEW = !System.getProperty("test").equals("old");
|
||||
static final boolean TEST_OLD = !System.getProperty("test").equals("new");
|
||||
|
||||
static transient boolean failed = false;
|
||||
static CountDownLatch cl = new CountDownLatch(1);
|
||||
static AtomicInteger count = new AtomicInteger();
|
||||
|
||||
public static void main(String[] args) throws Exception {
|
||||
// At the beginning, current subject is null
|
||||
test("", null);
|
||||
cl.await();
|
||||
if (failed) {
|
||||
throw new Exception("Failed");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Ensure the current subject is the expected Subject object.
|
||||
*
|
||||
* @param label label to print out
|
||||
* @param expected the expected Subject
|
||||
*/
|
||||
synchronized static void check(String label, Subject expected) {
|
||||
Subject cas = Subject.current();
|
||||
Subject accs = Subject.getSubject(AccessController.getContext());
|
||||
if (TEST_NEW && TEST_OLD && cas != accs) {
|
||||
failed = true;
|
||||
System.out.println(label + ": current " + s2s(cas)
|
||||
+ " but getSubject is " + s2s(accs));
|
||||
}
|
||||
Subject interested = TEST_NEW ? cas : accs;
|
||||
if (interested != expected) {
|
||||
failed = true;
|
||||
System.out.println(label + ": expected " + s2s(expected)
|
||||
+ " but see " + s2s(interested));
|
||||
} else {
|
||||
System.out.println(label + ": " + s2s(expected));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Recursively testing on current subject with getAs() and thread creations.
|
||||
*
|
||||
* @param name the current label
|
||||
* @param expected the expected Subject
|
||||
*/
|
||||
static Void test(String name, Subject expected) {
|
||||
// Now it's the expected current subject
|
||||
check(" ".repeat(name.length()) + "-> " + name, expected);
|
||||
// Recursively check, do not go infinity
|
||||
if (name.length() < 4) {
|
||||
Subject another = new Subject();
|
||||
another.getPrincipals().add(new RawPrincipal(name + "d"));
|
||||
// run with a new subject, inside current subject will be the new subject
|
||||
if (TEST_NEW) Subject.callAs(another, () -> test(name + 'c', another));
|
||||
if (TEST_OLD) Subject.doAs(another, (PrivilegedAction<Void>) () -> test(name + 'd', another));
|
||||
// run with null, inside current subject will be null
|
||||
if (TEST_NEW) Subject.callAs(null, () -> test(name + 'C', null));
|
||||
if (TEST_OLD) Subject.doAs(null, (PrivilegedAction<Void>) () -> test(name + 'D', null));
|
||||
// new thread, inside current subject is unchanged
|
||||
count.incrementAndGet();
|
||||
new Thread(() -> {
|
||||
try {
|
||||
test(name + 't', expected);
|
||||
try {
|
||||
Thread.sleep(500);
|
||||
} catch (Exception e) {
|
||||
throw new AssertionError(e);
|
||||
}
|
||||
// by this time, parent thread should have exited the
|
||||
// action and current subject reset, but here
|
||||
// current subject unchanged.
|
||||
test(name + 'T', expected);
|
||||
} finally {
|
||||
var n = count.decrementAndGet();
|
||||
if (n == 0) {
|
||||
cl.countDown();
|
||||
}
|
||||
assert n >= 0;
|
||||
}
|
||||
}).start();
|
||||
}
|
||||
// Now it's reset to original
|
||||
check(" ".repeat(name.length()) + "<- " + name, expected);
|
||||
return null;
|
||||
}
|
||||
|
||||
static class RawPrincipal implements Principal {
|
||||
|
||||
String name;
|
||||
RawPrincipal(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
@Override
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
}
|
||||
|
||||
static String s2s(Subject s) {
|
||||
return s == null ? null
|
||||
: s.getPrincipals().iterator().next().getName();
|
||||
}
|
||||
}
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2018, 2021, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -26,10 +26,6 @@
|
||||
* @bug 8214583
|
||||
* @summary Check that getSubject works after JIT compiler escape analysis.
|
||||
*/
|
||||
import java.security.AccessControlContext;
|
||||
import java.security.AccessController;
|
||||
import java.security.PrivilegedAction;
|
||||
import java.security.PrivilegedExceptionAction;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.HashSet;
|
||||
@ -44,9 +40,8 @@ public class DoAs {
|
||||
|
||||
for (int i = 0; i < 100_000; ++i) {
|
||||
final int index = i;
|
||||
Subject.doAs(subject, (PrivilegedExceptionAction<Integer>)() -> {
|
||||
AccessControlContext c1 = AccessController.getContext();
|
||||
Subject s = Subject.getSubject(c1);
|
||||
Subject.callAs(subject, () -> {
|
||||
Subject s = Subject.current();
|
||||
if (s != subject) {
|
||||
throw new AssertionError("outer Oops! " + "iteration " + index + " " + s + " != " + subject);
|
||||
}
|
||||
|
99
test/jdk/javax/security/auth/Subject/Exceptions.java
Normal file
99
test/jdk/javax/security/auth/Subject/Exceptions.java
Normal file
@ -0,0 +1,99 @@
|
||||
/*
|
||||
* Copyright (c) 2021, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
/*
|
||||
* @test
|
||||
* @bug 8267108
|
||||
* @library /test/lib
|
||||
* @summary Check that callAs and doAs throw the specified exceptions
|
||||
* @run main/othervm -Djava.security.manager=allow -Djdk.security.auth.subject.useTL=true Exceptions
|
||||
* @run main/othervm -Djava.security.manager=allow -Djdk.security.auth.subject.useTL=false Exceptions
|
||||
*/
|
||||
import jdk.test.lib.Asserts;
|
||||
|
||||
import javax.security.auth.Subject;
|
||||
import java.security.PrivilegedActionException;
|
||||
import java.security.PrivilegedExceptionAction;
|
||||
import java.util.concurrent.Callable;
|
||||
import java.util.concurrent.CompletionException;
|
||||
|
||||
public class Exceptions {
|
||||
|
||||
public static void main(String[] args) throws Exception {
|
||||
|
||||
// Checked exceptions are always wrapped
|
||||
new TestCase(() -> { throw new Exception("Hi"); })
|
||||
.testDoAs(PrivilegedActionException.class, Exception.class)
|
||||
.testCallAs(CompletionException.class, Exception.class);
|
||||
// PrivilegedActionException itself is checked
|
||||
new TestCase(() -> { throw new PrivilegedActionException(new Exception("Hi")); })
|
||||
.testDoAs(PrivilegedActionException.class, PrivilegedActionException.class, Exception.class)
|
||||
.testCallAs(CompletionException.class, PrivilegedActionException.class, Exception.class);
|
||||
|
||||
// Unchecked exception: rethrown by doAs(), wrapped by callAs()
|
||||
new TestCase(() -> { throw new RuntimeException("Hi"); })
|
||||
.testDoAs(RuntimeException.class)
|
||||
.testCallAs(CompletionException.class, RuntimeException.class);
|
||||
// CompletionException itself is unchecked
|
||||
new TestCase(() -> { throw new CompletionException(new Exception("Hi")); })
|
||||
.testDoAs(CompletionException.class, Exception.class)
|
||||
.testCallAs(CompletionException.class, CompletionException.class, Exception.class);
|
||||
}
|
||||
|
||||
static class TestCase {
|
||||
|
||||
final Callable<Void> action;
|
||||
TestCase(Callable<Void> action) {
|
||||
this.action = action;
|
||||
}
|
||||
|
||||
TestCase testDoAs(Class<?>... exceptions) {
|
||||
return test(true, exceptions);
|
||||
}
|
||||
|
||||
TestCase testCallAs(Class<?>... exceptions) {
|
||||
return test(false, exceptions);
|
||||
}
|
||||
|
||||
// Perform the action in doAs() or callAs() and inspect
|
||||
// the exception (and its causes, recursively) it throws
|
||||
private TestCase test(boolean doAs, Class<?>... exceptions) {
|
||||
int pos = 0;
|
||||
try {
|
||||
if (doAs) {
|
||||
Subject.doAs(null, (PrivilegedExceptionAction<Object>) action::call);
|
||||
} else {
|
||||
Subject.callAs(null, action::call);
|
||||
}
|
||||
} catch (Exception e) {
|
||||
while (e != null) {
|
||||
Asserts.assertEQ(e.getClass(), exceptions[pos++]);
|
||||
e = (Exception) e.getCause();
|
||||
}
|
||||
}
|
||||
// Make sure the list is the exact size
|
||||
Asserts.assertTrue(pos == exceptions.length);
|
||||
return this;
|
||||
}
|
||||
}
|
||||
}
|
63
test/jdk/javax/security/auth/Subject/FromACC.java
Normal file
63
test/jdk/javax/security/auth/Subject/FromACC.java
Normal file
@ -0,0 +1,63 @@
|
||||
/*
|
||||
* Copyright (c) 2021, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
import javax.security.auth.Subject;
|
||||
import javax.security.auth.x500.X500Principal;
|
||||
import java.security.AccessControlContext;
|
||||
import java.security.AccessController;
|
||||
import java.security.PrivilegedAction;
|
||||
|
||||
/*
|
||||
* @test
|
||||
* @bug 8267108
|
||||
* @summary confirm current installed subject specification
|
||||
* @run main/othervm -Djava.security.manager=allow FromACC
|
||||
* @run main/othervm -Djava.security.manager=disallow FromACC
|
||||
*/
|
||||
public class FromACC {
|
||||
public static void main(String[] args) throws Exception {
|
||||
var n = Subject.doAs(from("a"), (PrivilegedAction<AccessControlContext>)
|
||||
() -> AccessController.getContext());
|
||||
if (!get(Subject.getSubject(n)).equals("CN=a")) {
|
||||
throw new RuntimeException();
|
||||
}
|
||||
}
|
||||
|
||||
static Subject from(String name) {
|
||||
Subject s = new Subject();
|
||||
s.getPrincipals().add(new X500Principal("CN=" + name));
|
||||
return s;
|
||||
}
|
||||
|
||||
static String get(Subject s) {
|
||||
if (s == null) {
|
||||
return "none";
|
||||
}
|
||||
var v = s.getPrincipals(X500Principal.class);
|
||||
if (v == null || v.isEmpty()) {
|
||||
return "none";
|
||||
} else {
|
||||
return v.iterator().next().getName();
|
||||
}
|
||||
}
|
||||
}
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2003, 2011, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2003, 2021, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -28,9 +28,9 @@
|
||||
*/
|
||||
|
||||
import java.security.Principal;
|
||||
import java.security.PrivilegedAction;
|
||||
import java.util.Collections;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.Callable;
|
||||
import javax.security.auth.Subject;
|
||||
import javax.security.auth.x500.X500Principal;
|
||||
|
||||
@ -52,18 +52,18 @@ public class Synch {
|
||||
}
|
||||
}.start();
|
||||
for (int i = 0; i < 1000; i++) {
|
||||
Subject.doAs(
|
||||
Subject.callAs(
|
||||
subject,
|
||||
new PrivilegedAction() {
|
||||
public Object run() {
|
||||
return Subject.doAs(
|
||||
new Callable() {
|
||||
public Object call() {
|
||||
return Subject.callAs(
|
||||
new Subject(true,
|
||||
Collections.singleton(
|
||||
new X500Principal("CN=Claire")),
|
||||
Collections.EMPTY_SET,
|
||||
Collections.EMPTY_SET),
|
||||
new PrivilegedAction() {
|
||||
public Object run() {
|
||||
new Callable() {
|
||||
public Object call() {
|
||||
return null;
|
||||
}
|
||||
});
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2011, 2021, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -31,7 +31,7 @@
|
||||
*/
|
||||
|
||||
import java.io.FileOutputStream;
|
||||
import java.security.PrivilegedExceptionAction;
|
||||
import java.util.concurrent.Callable;
|
||||
import javax.security.auth.Subject;
|
||||
import javax.security.auth.kerberos.KerberosKey;
|
||||
import javax.security.auth.kerberos.KerberosPrincipal;
|
||||
@ -59,8 +59,8 @@ public class KrbCredSubKey {
|
||||
subj.getPrincipals().add(kp);
|
||||
subj.getPrivateCredentials().add(kk);
|
||||
|
||||
Subject.doAs(subj, new PrivilegedExceptionAction() {
|
||||
public Object run() throws Exception {
|
||||
Subject.callAs(subj, new Callable<>() {
|
||||
public Object call() throws Exception {
|
||||
GSSManager man = GSSManager.getInstance();
|
||||
GSSContext ctxt = man.createContext(man.createCredential(
|
||||
null, GSSCredential.INDEFINITE_LIFETIME,
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2012, 2021, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -29,9 +29,9 @@
|
||||
* @summary default principal can act as anyone
|
||||
*/
|
||||
|
||||
import java.security.PrivilegedActionException;
|
||||
import java.security.PrivilegedExceptionAction;
|
||||
import java.util.Objects;
|
||||
import java.util.concurrent.Callable;
|
||||
import java.util.concurrent.CompletionException;
|
||||
import javax.security.auth.Subject;
|
||||
import javax.security.auth.kerberos.KerberosKey;
|
||||
import javax.security.auth.kerberos.KerberosPrincipal;
|
||||
@ -122,10 +122,10 @@ public class ServiceCredsCombination {
|
||||
}
|
||||
final GSSManager man = GSSManager.getInstance();
|
||||
try {
|
||||
String result = Subject.doAs(
|
||||
subj, new PrivilegedExceptionAction<String>() {
|
||||
String result = Subject.callAs(
|
||||
subj, new Callable<String>() {
|
||||
@Override
|
||||
public String run() throws GSSException {
|
||||
public String call() throws GSSException {
|
||||
GSSCredential cred = man.createCredential(
|
||||
a == null ? null : man.createName(r(a), null),
|
||||
GSSCredential.INDEFINITE_LIFETIME,
|
||||
@ -139,7 +139,7 @@ public class ServiceCredsCombination {
|
||||
throw new Exception("Check failed: getInstance(" + a
|
||||
+ ") has name " + result + ", not " + b);
|
||||
}
|
||||
} catch (PrivilegedActionException e) {
|
||||
} catch (CompletionException e) {
|
||||
if (!"NOCRED".equals(b)) {
|
||||
throw new Exception("Check failed: getInstance(" + a
|
||||
+ ") is null " + ", but not one with name " + b);
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2008, 2018, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2008, 2021, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -26,8 +26,6 @@ import com.sun.security.auth.module.Krb5LoginModule;
|
||||
import java.io.IOException;
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.lang.reflect.Method;
|
||||
import java.security.PrivilegedActionException;
|
||||
import java.security.PrivilegedExceptionAction;
|
||||
import java.util.Arrays;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
@ -55,6 +53,8 @@ import java.io.ByteArrayInputStream;
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.security.Principal;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.Callable;
|
||||
import java.util.concurrent.CompletionException;
|
||||
|
||||
/**
|
||||
* Context of a JGSS subject, encapsulating Subject and GSSContext.
|
||||
@ -100,9 +100,9 @@ public class Context {
|
||||
Context out = new Context();
|
||||
out.s = s;
|
||||
try {
|
||||
out.cred = Subject.doAs(s, new PrivilegedExceptionAction<GSSCredential>() {
|
||||
out.cred = Subject.callAs(s, new Callable<GSSCredential>() {
|
||||
@Override
|
||||
public GSSCredential run() throws Exception {
|
||||
public GSSCredential call() throws Exception {
|
||||
GSSCredential cred = x.getDelegCred();
|
||||
if (cred == null && x.getCredDelegState() ||
|
||||
cred != null && !x.getCredDelegState()) {
|
||||
@ -111,8 +111,8 @@ public class Context {
|
||||
return cred;
|
||||
}
|
||||
});
|
||||
} catch (PrivilegedActionException pae) {
|
||||
throw pae.getException();
|
||||
} catch (CompletionException ce) {
|
||||
throw (Exception) ce.getCause();
|
||||
}
|
||||
out.name = name + " as " + out.cred.getName().toString();
|
||||
return out;
|
||||
@ -339,15 +339,15 @@ public class Context {
|
||||
*/
|
||||
public byte[] doAs(final Action action, final byte[] in) throws Exception {
|
||||
try {
|
||||
return Subject.doAs(s, new PrivilegedExceptionAction<byte[]>() {
|
||||
return Subject.callAs(s, new Callable<byte[]>() {
|
||||
|
||||
@Override
|
||||
public byte[] run() throws Exception {
|
||||
public byte[] call() throws Exception {
|
||||
return action.run(Context.this, in);
|
||||
}
|
||||
});
|
||||
} catch (PrivilegedActionException pae) {
|
||||
throw pae.getException();
|
||||
} catch (CompletionException ce) {
|
||||
throw (Exception) ce.getCause();
|
||||
}
|
||||
}
|
||||
|
||||
@ -612,9 +612,9 @@ public class Context {
|
||||
|
||||
public Context impersonate(final String someone) throws Exception {
|
||||
try {
|
||||
GSSCredential creds = Subject.doAs(s, new PrivilegedExceptionAction<GSSCredential>() {
|
||||
GSSCredential creds = Subject.callAs(s, new Callable<GSSCredential>() {
|
||||
@Override
|
||||
public GSSCredential run() throws Exception {
|
||||
public GSSCredential call() throws Exception {
|
||||
GSSManager m = GSSManager.getInstance();
|
||||
GSSName other = m.createName(someone, GSSName.NT_USER_NAME);
|
||||
if (Context.this.cred == null) {
|
||||
@ -631,8 +631,8 @@ public class Context {
|
||||
out.cred = creds;
|
||||
out.name = name + " as " + out.cred.getName().toString();
|
||||
return out;
|
||||
} catch (PrivilegedActionException pae) {
|
||||
Exception e = pae.getException();
|
||||
} catch (CompletionException ce) {
|
||||
Exception e = (Exception) ce.getCause();
|
||||
if (e instanceof InvocationTargetException) {
|
||||
throw (Exception)((InvocationTargetException) e).getTargetException();
|
||||
} else {
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2009, 2018, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2009, 2021, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -83,6 +83,8 @@ import org.ietf.jgss.GSSManager;
|
||||
import sun.security.jgss.GSSUtil;
|
||||
import sun.security.krb5.Config;
|
||||
import java.util.Base64;
|
||||
import java.util.concurrent.Callable;
|
||||
import java.util.concurrent.CompletionException;
|
||||
|
||||
/**
|
||||
* Basic JGSS/krb5 test with 3 parties: client, server, backend server. Each
|
||||
@ -375,9 +377,9 @@ public class HttpNegotiateServer {
|
||||
|
||||
Subject subject = context.getSubject();
|
||||
|
||||
final PrivilegedExceptionAction<Object> test_action
|
||||
= new PrivilegedExceptionAction<Object>() {
|
||||
public Object run() throws Exception {
|
||||
final Callable<Object> test_action
|
||||
= new Callable<Object>() {
|
||||
public Object call() throws Exception {
|
||||
testConnect();
|
||||
return null;
|
||||
}
|
||||
@ -387,10 +389,10 @@ public class HttpNegotiateServer {
|
||||
"with the the logged in subject.");
|
||||
|
||||
try {
|
||||
Subject.doAs(subject, test_action);
|
||||
Subject.callAs(subject, test_action);
|
||||
System.err.println("\n\nConnection succeed when executing " +
|
||||
"with the the logged in subject.");
|
||||
} catch (PrivilegedActionException e) {
|
||||
} catch (CompletionException e) {
|
||||
System.err.println("\n\nFailure unexpected when executing " +
|
||||
"with the the logged in subject.");
|
||||
e.printStackTrace();
|
||||
@ -466,9 +468,9 @@ public class HttpNegotiateServer {
|
||||
krb5.login();
|
||||
krb5.commit();
|
||||
m = GSSManager.getInstance();
|
||||
cred = Subject.doAs(s, new PrivilegedExceptionAction<GSSCredential>() {
|
||||
cred = Subject.callAs(s, new Callable<GSSCredential>() {
|
||||
@Override
|
||||
public GSSCredential run() throws Exception {
|
||||
public GSSCredential call() throws Exception {
|
||||
System.err.println("Creating GSSCredential");
|
||||
return m.createCredential(
|
||||
null,
|
||||
@ -494,12 +496,7 @@ public class HttpNegotiateServer {
|
||||
if (auth == null) { // First request
|
||||
Headers map = exch.getResponseHeaders();
|
||||
map.set (reqHdr, scheme); // Challenge!
|
||||
c = Subject.doAs(s, new PrivilegedExceptionAction<GSSContext>() {
|
||||
@Override
|
||||
public GSSContext run() throws Exception {
|
||||
return m.createContext(cred);
|
||||
}
|
||||
});
|
||||
c = Subject.callAs(s, () -> m.createContext(cred));
|
||||
exch.getHttpContext().getAttributes().put("GSSContext", c);
|
||||
return new com.sun.net.httpserver.Authenticator.Retry(err);
|
||||
} else { // Later requests
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2015, 2018, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2015, 2021, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -36,7 +36,6 @@ import org.ietf.jgss.GSSManager;
|
||||
import sun.security.krb5.Config;
|
||||
import javax.security.auth.Subject;
|
||||
import javax.security.auth.kerberos.KerberosTicket;
|
||||
import java.security.PrivilegedExceptionAction;
|
||||
|
||||
public class LongLife {
|
||||
|
||||
@ -72,8 +71,7 @@ public class LongLife {
|
||||
|
||||
Context c = Context.fromJAAS("client");
|
||||
|
||||
GSSCredential cred = Subject.doAs(c.s(),
|
||||
(PrivilegedExceptionAction<GSSCredential>)
|
||||
GSSCredential cred = Subject.callAs(c.s(),
|
||||
()-> {
|
||||
GSSManager m = GSSManager.getInstance();
|
||||
return m.createCredential(GSSCredential.INITIATE_ONLY);
|
||||
|
Loading…
Reference in New Issue
Block a user