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