Thanks for the quick reply ! Indeed I didn't add the JAASLoginInterceptor because the implementation was rather oriented to user/password(wich indeed works well with WSS4JInteceptor...). Actually, there is an X509 principal after de WSS4JInterceptor but no Principal for groups so I need to trigger my own LoginModule with the right callbackhandler to get those groups. I wonder if I shouldn't write my own interceptor base on JAASLoginInterceptor cause some part explicitly check for a username/password. Best Regards, Claude
2017-01-31 12:06 GMT+01:00 Colm O hEigeartaigh <[email protected]>: > On Tue, Jan 31, 2017 at 10:05 AM, Claude Libois <[email protected]> > wrote: > > > > > I try to do some authorization after a SOAP call with WSS Security and > > digitial signature. My JAAS principal is created based on Signing > > certificate and we do a lookup in the LDAP to get some role. I wanted to > > filter my service to give access only to some role. > > > WSS4J validates the Signature and stores the principal, and CXF creates a > security context. As there is no JAAS Subject at this stage in your > example, it just creates a security context returning false for > "isUserInRole" (so yes, this is intentional). > > You have two options: > > a) Override the default SignatureTrustValidator in WSS4J. After successful > validation, then write some code to authenticate the principal using JAAS + > save the JAAS Subject on the "Credential" the Validator returns. If you do > this, CXF will automatically set up the security context using the roles > retrieved from the JAAS Subject, and you don't need then to use the > JAASLoginInterceptor at all. > > b) Keep WSS4J as it is, but then you need to tell the JAASLoginInterceptor > how to find the principal by writing a CallbackHandler which will examine > the existing security context and return the principal name to use for > JAAS. You can do this by setting the "callbackHandlerProviders" property of > JAASLoginInterceptor...take a look at the source and the default > implementations, it should be fairly straightforward to implement. > > Colm. > > > > > For this I did the > > following configuration: > > > > <bean class="org.apache.cxf.interceptor.security.JAASLoginInterceptor" > > id="jaas"> <!-- user for UserToken Authentication--> > > <property name="roleClassifier" value="***"/> > > <property name="contextName" value="***"/> > > </bean> > > <bean id="authorizationInterceptor" > > class="org.apache.cxf.interceptor.security.SimpleAuthorizing > Interceptor"> > > <property name="globalRoles" value="***"/> > > </bean> > > <bean id="mapAggregator" > > class="org.apache.cxf.ws.addressing.MAPAggregator"> <!-- required for > > WSA see http://cxf.apache.org/docs/wsaconfiguration.html--> > > <property name="allowDuplicates" value="false"/> > > <property name="addressingRequired" value="true"/> > > </bean> > > <bean id="mapCodec" > > class="org.apache.cxf.ws.addressing.soap.MAPCodec"/> <!-- required for > > WSA see http://cxf.apache.org/docs/wsaconfiguration.html--> > > <bean id="exceptionThrower" > > class="be.leforem.service.external.offresemploi.HttpExceptionThrower"/> > > <bean id="faultInterceptor" > > class="be.leforem.service.external.offresemploi.FaultInterceptor"/> > > <cxf:bus bus="cxf" > > > <cxf:outFaultInterceptors> > > <ref component-id="faultInterceptor"/> > > </cxf:outFaultInterceptors> > > </cxf:bus> > > > > <camelcxf:cxfEndpoint id="***" > > address="camel://direct:***" > > serviceName="*"** > > endpointName="***" > > wsdlURL="META-INF/wsdl/***.wsdl" > > publishedEndpointUrl="{{wsdlPublicUrl}}" > > xmlns:c="***"> <!-- Service with Certificate > > usage(signing)--> > > <camelcxf:properties> > > <entry key="ws-security.timestamp.timeToLive" > > value="${wss.timestamp.timeToLive}"/> > > <entry key="ws-security.timestamp.futureTimeToLive" > > value="${wss.timestamp.futureTimeToLive}"/> > > <entry key="ws-security.enable.timestamp.cache" value="true"/> > > <!-- avoid replay attack--> > > <entry key="ws-security.callback-handler" > > value-ref="passwordCallback" /> > > <entry key="ws-security.signature.properties" > > value="file:${karaf.home}***"/> > > <entry key="ws-security.encryption.properties" > > value="file:${karaf.home}***"/> > > <entry key="ws-security.encryption.username" > > value="useReqSigCert"/> > > <entry key="ws-security.enableRevocation" value="${useCrl}"/> > > <entry key="ws-security.return.security.error" value="true"/> > > <!-- return more explicit error message with ws-security --> > > <entry key="ws-security.subject.cert.constraints" value=".*"/> > > <entry key="schema-validation-enabled" > > value="${schemaValidations}"/> > > <entry key="sigIssuerCertConstraints" value="${ > > issuerCertConstraints}"/> > > <entry key="ws-security.validate.token" value="true"/> <!-- > > validate token(Certificate here)--> > > </camelcxf:properties> > > <camelcxf:inInterceptors> > > <ref component-id="authorizationInterceptor"/> > > <ref component-id="mapAggregator"/> <!-- required for WSA > > see http://cxf.apache.org/docs/wsaconfiguration.html--> > > <ref component-id="mapCodec"/> > > </camelcxf:inInterceptors> > > <camelcxf:inFaultInterceptors> > > <ref component-id="mapAggregator"/> <!-- required for WSA > > see http://cxf.apache.org/docs/wsaconfiguration.html--> > > <ref component-id="mapCodec"/> > > </camelcxf:inFaultInterceptors> > > <camelcxf:outInterceptors> > > <ref component-id="mapAggregator"/> <!-- required for WSA see > > http://cxf.apache.org/docs/wsaconfiguration.html--> > > <ref component-id="mapCodec"/> > > </camelcxf:outInterceptors> > > <camelcxf:outFaultInterceptors> > > <ref component-id="mapAggregator"/> <!-- required for WSA see > > http://cxf.apache.org/docs/wsaconfiguration.html--> > > <ref component-id="mapCodec"/> > > </camelcxf:outFaultInterceptors> > > </camelcxf:cxfEndpoint> > > > > I have noticed that the WSS4JInterceptor create a SecurityContext this > way: > > > > protected SecurityContext createSecurityContext(final Principal p) { > > return new SecurityContext() { > > > > public Principal getUserPrincipal() { > > return p; > > } > > > > public boolean isUserInRole(String arg0) { > > return false; > > } > > }; > > } > > > > So there is no way my authorizaiton will work due to isUserInRole not > > really implemented. > > My question is: > > - Is it intentionnal ? > > - Is there another way than rewriting this class to force a real role > base > > verification such the one we can find in the JAASLoginInterceptor ? > > > > protected SecurityContext createSecurityContext(String name, Subject > > subject) { > > if (getRoleClassifier() != null) { > > return new RolePrefixSecurityContextImpl(subject, > > getRoleClassifier(), > > > getRoleClassifierType()); > > } else { > > return new DefaultSecurityContext(name, subject); > > } > > } > > > > - Is there any documentation to do the things properly ? I was quite > > cumbersome to find how to achieve this > > Best Regards, > > Claude > > > > > > -- > Colm O hEigeartaigh > > Talend Community Coder > http://coders.talend.com >
