How to create SubjectCanonicalizationContext

Joey Wang carbon_60 at yahoo.com
Thu Jan 21 22:46:52 EST 2016


 Hi, Shibboleth experts, We want to extend the idp authentication flow to integrateShibboleth IDP with our backend SSO system. I am very new to Shibboleth,so I want to learn how to write a simplest authentication flow extension as mystarting point. But I do not know how to create and pass theSubjectCanonicalizationContext from the authentication flow to c14n subflow. Reading the Shibboleth document, Authentication - Identity Provider 3 - Confluence, the endresult of the authentication flow is to produce an AuthenticationResult as partof AuthenticationContext.  SoI started out by developing a dummy authentication flow that does nothing butsimply populates a hardcoded UsernamePrincipal object into AuthenticationResultobject and then add the AuthenticationResult object to theAuthenticationContext: 1.    Create UsernameContextwith hardcoded username and add it to AuthenticationContext. Not sure if I needto do this.2.    CreateAuthenticationResult Object3.    Create a javax.security.auth.Subjectwith hardcoded Principals and add it to AuthenticationResult object4.    Finally, addAuthenticationResult Object to AuthenticationContext.5.    I also created aSubjectContext as child of ProfileRequestContext, but not sure if it is neededor not.6.    Change the flow toidp.authn.flows= dummy in idp.properties Hereis my flow definition:  <flow xmlns="http://www.springframework.org/schema/webflow"      xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"      xsi:schemaLocation="http://www.springframework.org/schema/webflowhttp://www.springframework.org/schema/webflow/spring-webflow.xsd"      parent="authn.abstract,authn/conditions">       <!-- Rudimentary impediment to directexecution of subflow. -->    <inputname="calledAsSubflow" type="boolean"required="true" />     <on-start>                               <!-- Get authenticationcontext and usernamePassword context. we expectusernamePassword context is null if we did not start with Password flow first-->        <evaluateexpression="opensamlProfileRequestContext.getSubcontext(T(net.shibboleth.idp.authn.context.AuthenticationContext))"result="flowScope.authenticationContext" />        <evaluateexpression="authenticationContext.getSubcontext(T(net.shibboleth.idp.authn.context.UsernamePasswordContext))"result="flowScope.usernamePasswordContext" />                                <!--Create usernamecontext subcontext as child of authncontext, put jwang asusername -->        <evaluateexpression="flowScope.authenticationContext.getSubcontext(T(net.shibboleth.idp.authn.context.UsernameContext),true)" result="flowScope.usernameContext" />                               <evaluate expression="flowScope.usernameContext.setUsername('jwang')" />                                <!--Create subject with principals -->                               <evaluate expression="new javax.security.auth.Subject()"result="flowScope.subject" />                               <evaluate expression="flowScope.subject.getPrincipals().add(newnet.shibboleth.idp.authn.principal.UsernamePrincipal(flowScope.usernameContext.getUsername()))"/>                               <evaluate expression="flowScope.subject.getPrincipals().add(newnet.shibboleth.idp.saml.authn.principal.AuthnContextClassRefPrincipal('urn:oasis:names:tc:SAML:2.0:ac:classes:PasswordProtectedTransport'))"/>                               <evaluate expression="flowScope.subject.getPrincipals().add(newnet.shibboleth.idp.saml.authn.principal.AuthnContextClassRefPrincipal('urn:oasis:names:tc:SAML:2.0:ac:classes:Password'))"/>                               <evaluate expression="flowScope.subject.getPrincipals().add(newnet.shibboleth.idp.saml.authn.principal.AuthenticationMethodPrincipal('urn:oasis:names:tc:SAML:1.0:am:password'))"/>                                <!--Create Authenresult with subject -->                               <evaluate expression="new net.shibboleth.idp.authn.AuthenticationResult('authn/dummy',flowScope.subject)" result="flowScope.authnResult" />        <evaluateexpression="flowScope.authenticationContext.setAuthenticationResult(flowScope.authnResult)" />                                                               <!-- Create SubjectContext as child of ProfileRequestContext and addauthnresults and subject -->        <evaluate expression="opensamlProfileRequestContext.getSubcontext(T(net.shibboleth.idp.authn.context.SubjectContext),true)" result="flowScope.subjectContext" />        <evaluateexpression="flowScope.subjectContext.getAuthenticationResults()"result="flowScope.authnResultMap"  />                               <evaluate expression="flowScope.authnResultMap.put(flowScope.authnResult.getAuthenticationFlowId(),flowScope.authnResult)"  />                               <evaluate expression="flowScope.subjectContext.setPrincipalName(flowScope.usernameContext.getUsername())" />                                                              <!-- Retrieve subjectCanonicalContext from Password flow-->                               <evaluate expression="opensamlProfileRequestContext.getSubcontext(T(net.shibboleth.idp.authn.context.SubjectCanonicalizationContext))"result="flowScope.subjectCanonicalContext" />     </on-start>     <!-- Display Dummy page -->    <view-state id="dummyView"view="dummy">        <on-render>           <evaluate expression="environment"result="viewScope.environment" />           <evaluateexpression="flowRequestContext.getExternalContext().getNativeRequest()"result="viewScope.request" />       </on-render>         <transitionto="dummyResponse" />    </view-state>         <action-stateid="dummyResponse">                               <!--Create SubjectCanonicalizationContext >                               <evaluate expression="opensamlProfileRequestContext.getSubcontext(T(net.shibboleth.idp.authn.context.SubjectCanonicalizationContext),true)" result="flowScope.subjectCanonicalContext" />                               <evaluate expression="flowScope.subjectCanonicalContext.setPrincipalName(flowScope.subjectContext.getPrincipalName())" result="flowScope.subjectCanonicalContext" />                               <evaluate expression="flowScope.subjectCanonicalContext.setSubject(flowScope.subject)" result="flowScope.subjectCanonicalContext" /-->                               <evaluate expression="'proceed'"/>        <!-- Proceedon successful authentication -->        <transitionto="proceed" />    </action-state>     <end-state id="proceed"/> </flow>  My dummy.vm is nothing but a submit button:           <form action="$flowExecutionUrl" method="post">               <input type="text" name="_eventId_proceed"value="transition" />                                                               <button class="form-element form-button" type="submit"name="_eventId_submit" value="submit">Submit</button>         </form> The error I got is InvalidSubectCanonicalizationContext:  2016-01-22 02:18:58,051 - DEBUG[org.springframework.webflow.engine.SubflowState:99] - Calling subflow'c14n/authn' with input map['calledAsSubflow' -> true]2016-01-22 02:18:58,051 - DEBUG[org.springframework.binding.mapping.impl.DefaultMapper:60] - Beginning mappingbetween source [org.springframework.webflow.core.collection.LocalAttributeMap]and target [org.springframework.webflow.engine.impl.RequestControlContextImpl]2016-01-22 02:18:58,057 - DEBUG[org.springframework.binding.mapping.impl.DefaultMapping:147] - Adding mappingresult [Success at 39c9cc37 mapping = calledAsSubflow ->flowScope.calledAsSubflow, code = 'success', error = false, originalValue =true, mappedValue = true]2016-01-22 02:18:58,057 - DEBUG[org.springframework.binding.mapping.impl.DefaultMapper:69] - Completingmapping between source[org.springframework.webflow.core.collection.LocalAttributeMap] and target[org.springframework.webflow.engine.impl.RequestControlContextImpl]; totalmappings = 1; total errors = 02016-01-22 02:18:58,057 - DEBUG[org.springframework.webflow.engine.ActionState:189] - Entering state'PopulateSubjectCanonicalizationContext' of flow 'c14n/authn'2016-01-22 02:18:58,058 - DEBUG[org.springframework.webflow.execution.ActionExecutor:49] - Executing[EvaluateAction at 6f7e4c84 expression = PopulateSubjectCanonicalizationContext,resultExpression = [null]]2016-01-22 02:18:58,058 - DEBUG [org.springframework.webflow.execution.AnnotatedAction:142]- Putting action execution attributes map[[empty]]2016-01-22 02:18:58,062 - DEBUG[org.springframework.beans.factory.support.DefaultListableBeanFactory:448] -Creating instance of bean 'PopulateSubjectCanonicalizationContext'2016-01-22 02:18:58,100 - DEBUG[org.springframework.beans.factory.support.DefaultListableBeanFactory:251] -Returning cached instance of singleton bean'shibboleth.PostLoginSubjectCanonicalizationFlows'2016-01-22 02:18:58,105 - DEBUG[org.springframework.beans.factory.support.DefaultListableBeanFactory:1678] -Invoking init method  'initialize' on bean with name'PopulateSubjectCanonicalizationContext'2016-01-22 02:18:58,110 - DEBUG[org.springframework.beans.factory.support.DefaultListableBeanFactory:484] -Finished creating instance of bean 'PopulateSubjectCanonicalizationContext'2016-01-22 02:18:58,111 - DEBUG[org.springframework.webflow.execution.ActionExecutor:49] - Executing net.shibboleth.idp.authn.impl.PopulateSubjectCanonicalizationContext at 478796162016-01-22 02:18:58,111 - DEBUG[org.springframework.webflow.execution.ActionExecutor:53] - Finished executing net.shibboleth.idp.authn.impl.PopulateSubjectCanonicalizationContext at 47879616;result = InvalidSubjectCanonicalizationContext
 The Shibboleth document says that upon successfulauthentication, a SubjectCanonicalizationContext object should be created andpassed on to the Subject Canonicalization subflow. So my question is that how Ican create the SubjectCanonicalizationContext object? I looked at the samplesin the document page https://wiki.shibboleth.net/confluence/display/IDP30/Contributions+and+Extensions,but none of them seems to have a step to create theSubjectCanonicalizationContext.  I also tried to add the above authentication flow as asubflow of the authn/Password flow by modifying the conditions-flow.xml:    <action-stateid="ValidateUsernamePassword">        <evaluateexpression="ValidateUsernamePassword" />        <evaluateexpression="'dummy'" />        <transitionon="dummy" to="dummyAuth" />       <subflow-state id="dummyAuth"subflow="authn/dummy">        <inputname="calledAsSubflow" value="true" />        <transitionon="proceed" to="proceed" />    </subflow-state> If I do that, I then successfully passed and everythingworked fine. So the authn/Password flow must have created theSubjectCanonicalizationContext successfully, but I do not know how to do thatif I run my standalone authn/dummy sublow. I am running Shibboleth idp 3.2.1 on Jetty 9.2. Any help would be greatly appreciated. Thanks, Joey 
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://shibboleth.net/pipermail/dev/attachments/20160122/569222f2/attachment-0001.html>


More information about the dev mailing list