サブジェクトを取得するには、LoginModuleとValveの組み合わせを使用できます。認証が開始される前にバルブが呼び出されるという事実は、ここで私たちを助けています。バルブが呼び出されると、セッションがThreadLocalに配置され(JBOSSが要求をThreadLocalに保存する方法と同様)、後でLoginModule.commit()が呼び出されると、サブジェクトがセッションに保存されます。
これを構成するには、以下のクラスのコンパイル済みコードをjarに追加し、$ CATALINA_BASE /lib/の下に配置します。
package my.test;
import java.io.IOException;
import java.util.Map;
import javax.security.auth.Subject;
import javax.security.auth.callback.CallbackHandler;
import javax.security.auth.login.LoginException;
import javax.security.auth.spi.LoginModule;
import javax.servlet.ServletException;
import org.apache.catalina.Session;
import org.apache.catalina.connector.Request;
import org.apache.catalina.connector.Response;
import org.apache.catalina.valves.ValveBase;
/**
* Use following class to retrieve subject in your HTTPServlet when using Tomcat.
*/
public class ContainerServices extends ValveBase implements LoginModule {
// Key to revtieve subject from session.
public static final String SUBJECT_KEY =
"javax.security.auth.Subject.container";
/**
* Session for current thread.
*/
static InheritableThreadLocal<Session> sessionHolder =
new InheritableThreadLocal<Session>();
// JAAS Subject being authenticated.
private Subject subject;
// Invoke the value.
public void invoke(Request request, Response response) throws IOException,
ServletException {
sessionHolder.set(request.getSessionInternal(true));
try {
// Next in the invocation chain
getNext().invoke(request, response);
} finally {
sessionHolder.remove();
}
}
// Initialize the login module
public void initialize(Subject subject, CallbackHandler callbackHandler,
Map<String, ?> sharedState, Map<String, ?> options) {
this.subject = subject;
}
// Store subject to session.
public boolean commit() throws LoginException {
Session session = sessionHolder.get();
if (session != null) {
session.getSession().setAttribute(ContainerServices.SUBJECT_KEY, subject);
}
return true;
}
// not used
public boolean abort() throws LoginException {
return false;
}
// not used
public boolean login() throws LoginException {
return true;
}
// not used
public boolean logout() throws LoginException {
return true;
}
}
$ CATALINA_BASE / conf / server.xmlで、次のValve構成を要素の子として追加します。
<Valve className="my.test.ContainerServices" />
jaas.configファイルで、LoginModuleと同じクラスを追加します。
DummyAppLogin {
my.test.ContainerServices required debug=true;
my.test.DummyAppLoginModule required debug=true;
};
ログイン後、以下を使用して認証済みサブジェクトを取得できます。
session.getAttribute( ContainerServices.SUBJECT_KEY );