Hi Filip,

I believe there is a way of doing this without resorting to ThreadLocals.
In your custom Validator implementation, trying setting the custom
Principal you are creating on the returned Credential Object. WSS4J's
SAMLTokenProcessor, for example, has the following code:

 else if (credential.getPrincipal() != null) {
     result.put(WSSecurityEngineResult.TAG_PRINCIPAL,
credential.getPrincipal());
 }

This will result in the created Principal Object being set on the security
context, instead of the SAMLTokenPrincipal. You should be able to access it
in the ClaimsHandler with something like:

MessageContext messageCtx =
parameters.getWebServiceContext().getMessageContext();
SecurityContext secCtx =
(SecurityContext)messageCtx.get(SecurityContext.class.getName());
secCtx.getUserPrincipal();

Colm.



On Mon, Jan 27, 2014 at 2:55 PM, Hoefer, Filip <[email protected]> wrote:

> Hi,
>
> Unfortunately, the trick does not work for me. In my environment, even the
> STS validator sometimes runs in a different thread than the ClaimsHandler.
> I will probably have to implement an own STS. Anyway, many thanks for your
> support, at least I have investigated all possible options.
>
> Best regards,
>
>    Filip
>
> -----Original Message-----
> From: Andrei Shakirin [mailto:[email protected]]
> Sent: Friday, January 24, 2014 2:31 PM
> To: [email protected]
> Cc: Colm O hEigeartaigh
> Subject: RE: (Fediz) STS - passing info from LoginModule to ClaimsHandler
>
>
> 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
>



-- 
Colm O hEigeartaigh

Talend Community Coder
http://coders.talend.com

Reply via email to