Hi,
I used ThreadLocal not in LoginModule itself, but in STS validator invoking
JAAS for login:
<bean id="validator" class="org.sopera.csg.tesbext.sts.jaas.JAASValidator">
<argument value="sts-ut" />
</bean>
<jaxws:endpoint id="utSTS" implementor="#stsProvider"
address="/SecurityTokenService/UT"
wsdlLocation="wsdl/ws-trust-1.4-service.wsdl"
xmlns:wst="http://docs.oasis-open.org/ws-sx/ws-trust/200512/"
serviceName="wst:SecurityTokenService" endpointName="wst:UT_Port">
<jaxws:properties>
<entry key="ws-security.ut.validator" value-ref="validator" />
</jaxws:properties>
</jaxws:endpoint>
public class JAASValidator implements Validator {
...
@Override
public Credential validate(Credential credential, RequestData data) throws
WSSecurityException {
UsernameToken userNameToken = credential.getUsernametoken();
validateUserNameToken(userNameToken);
try {
STSCallBackHandler callbackHandler = new
STSCallBackHandler(userNameToken, null);
LoginContext lc = new LoginContext(this.contextName,
callbackHandler);
lc.login();
Subject subject = lc.getSubject();
SecContext.setSubject(subject);
...
} catch (LoginException e) {
throw new WSSecurityException(e.getMessage(), e);
}
}
The validator is always called in the same thread with ClaimsHandler , but not
sure is this a solution for you.
The clean way will be to extend CalimsHandler.retrieveClaimValues() with the
security context subject argument and pass it through.
@Colm: do you see more elegant way to proceed that?
Regards,
Andrei.
> -----Original Message-----
> From: Hoefer, Filip [mailto:[email protected]]
> Sent: Freitag, 24. Januar 2014 12:56
> To: [email protected]
> Subject: RE: (Fediz) STS - passing info from LoginModule to ClaimsHandler
>
> Hello,
>
> Unfortunately, it appears that the LoginModule and the ClaimsHandler
> sometimes each use a different thread to handle a single request. Therefore,
> a ThreadLocal variable does not reliably facilitate state sharing.
>
> @Andrei: Did you get it running in your environment?
>
> @others: Any other ideas?
>
> Thank you
>
> Filip
>
> -----Original Message-----
> From: Hoefer, Filip [mailto:[email protected]]
> Sent: Wednesday, January 22, 2014 4:59 PM
> To: [email protected]
> Subject: RE: (Fediz) STS - passing info from LoginModule to ClaimsHandler
>
>
> Hi Andrei,
>
> Many thanks for your response! Your suggestion really appears to be the
> only viable solution at this time. It also occurred to us that we could use
> the
> subject Name to carry an internal ID from LoginModule to ClaimsHandler and
> then rewrite it to an external ID in ClaimsHandler. Unfortunately, rewriting
> the NameID value in ClaimsHandler has no effect. So I think I will go ahead
> with your suggestion.
>
> Filip
>
> -----Original Message-----
> From: Andrei Shakirin [mailto:[email protected]]
> Sent: Wednesday, January 22, 2014 10:36 AM
> To: [email protected]
> Subject: RE: (Fediz) STS - passing info from LoginModule to ClaimsHandler
>
>
> Hi,
>
> Yep, I had the similar case in STS: custom claims handler should validate user
> role received in RST as claim.
> However user role is determined in LoginModule through JAAS (invoked by
> ws-security.ut.validator validator).
> Therefore it was necessary to pass Subject/Principle from the LoginModule
> to ClaimHandler for validation.
>
> We did not find better solution as introducing custom SecurityContext with
> ThreadLocal:
>
> public final class SecContext {
> static ThreadLocal<Subject> subject = new ThreadLocal<Subject>();
> private SecContext() {
> }
> public static void setSubject(Subject subject2) {
> SecContext.subject.set(subject2);
> }
> public static Subject getSubject() {
> return subject.get();
> }
> }
>
> Validator:
> LoginContext lc = new LoginContext(this.contextName,
> callbackHandler);
> lc.login();
> Subject subject = lc.getSubject();
> SecContext.setSubject(subject);
>
> Claim Handler:
> Subject subject = SecContext.getSubject();
> Set<Principal> groups = subject.getPrincipals();
> List<String> roles = new ArrayList<String>();
> for (Principal group : groups) {
> if
> ("org.apache.karaf.jaas.boot.principal.RolePrincipal".equals(group.getClass()
> .getName())) {
> roles.add(group.getName());
> }
> }
> ...
>
> I think it will be nice to provide a possibility to access all custom
> Principles in
> ClaimsHandler - will think about that.
>
> Regards,
> Andrei.
>
> > -----Original Message-----
> > From: Hoefer, Filip [mailto:[email protected]]
> > Sent: Dienstag, 21. Januar 2014 13:16
> > To: [email protected]
> > Subject: (Fediz) STS - passing info from LoginModule to ClaimsHandler
> >
> > Hello,
> >
> > I am implementing a custom LoginModule and a custom ClaimsHandler for
> > the Fediz STS. The custom classes are integrated into Fediz via config
> > files, no problem. However, I do not know how to pass information from
> > my LoginModule to my ClaimsHandler. I create a custom Principal (with
> > custom
> > claims) in the LoginModule based on authentication via an external
> > security server. The problem is that the ClaimsHandler always only
> > receives a SAMLTokenPrincipal which will not give me access to the
> > custom claims. So far, do not see any alternative to accessing user
> > account via the identifier from SAMLTokenPrincipal.getName(). But that
> > only gives me access to the static user account, not to the transient state
> created during login.
> >
> > Please let me know if I oversee something, any help is appreciated.
> >
> > Kind regards,
> >
> > Filip Hofer