How to implement SPNEGO as web flow for IdP V3

Cantor, Scott cantor.2 at osu.edu
Thu Feb 26 10:25:35 EST 2015


On 2/26/15, 12:59 PM, "Daniel Lutz" <daniel.lutz at switch.ch> wrote:



>According to some of my observations, the IdP creates a
>new session for the client quite early, so that this
>session is available during the authentication flow
>(cookie JSESSIONID). Furthermore, each flow has a
>conversation identifier.

Well, the container creates that session. In V2, that session never got 
used for much of anything, but in V3, SWF relies on that session by 
default as its session mechanism. Within that session, you can have 
multiple flows executing, which is what the conversation identifier does. 
Each flow has an execution key that goes back and forth that recovers the 
conversation state of the flow so it knows what to do next.

The actual IdP session is not this. That's maintained outside the 
container session explicitly. But authentication flows don't generally 
need to know anything about the IdP session or deal with it, unless 
they're needing to examine previous authentication results to do things.

>I have the following idea how to implement SPNEGO
>using SWF:
>
>- The initial action redirects the browser to a specific
>  URL that includes the flow's conversation identifier.

Authentication flows in the IdP are subflows. What that means is they're 
never called themselves, they get run internally by a selection engine 
that itself is a subflow. The "flow" at the top level is a profile flow. 
e.g. SAML 2 SSO is a profile flow. The URL, therefore, is a binding 
endpoint that you're familiar with from V2, and the URL can never be 
anything different for the life of the flow. The execution key parameter 
is the only thing added to the URL in most cases.

To redirect to a different URL, you have to do a lot of stuff. To avoid 
that work, you use the External login flow if you want to do that, because 
it handles the "stuff" for you.

Whether that's desirable or not depends on the login approach and how 
effective it is if it's done inside the flow or outside it.

>- When the browser sends a subsequent request to this
>  URL, the actual SPNEGO negotiation begins, i.e. the
>  flow sends an HTTP 401 "Unauthorized" status back to
>  the browser.

Flows can control the HTTP responses, but it can get tricky to do that in 
the middle of a flow unless the client can be made to properly issue the 
next request with the flow execution key in the URL and pick back up where 
you leave off. In general, actual UI within a flow MUST be a view-state, 
or things get complex. It's possible with some work to use views to render 
a simple response with just an HTTP status, so sometimes that simplifies 
it.

As an example, I could never get basic-auth to work if I issued the 
challenge myself, I think because the client never understood to issue the 
next request with the updated flow execution key (I had no place to tell 
it "I need you to come back to a new URL, not the one that resulted in the 
challenge"). I'm not sure this will work out much differently because this 
is all happening under the covers in the client.

>This leads me to the following questions:
>- How can an SWF state do a redirection?

A view-state can be coded to have a view property that is a redirect.

e.g. system/flows/authn/external-authn-flow.xml

But you can't do that to advance within a flow. Flows don't generally 
redirect to themselves, they issue a response so that the client requests 
the same URL with the updated execution key. But any result that makes 
that happen would work in theory.

>- How can an SWF state respond with an HTTP 401 "Unauthorized"
>  status?

Actions can access the underlying servlet response and write to it, and 
there's a way to mark the response so that it's complete, but the problem 
is that without a view-state, the flow will keep trying to advance to the 
next action state. That basically breaks it.

>- How does the special URL containing the flow conversation
>  identifier need to look like? Is it possible for the IdP
>  to select the current flow based on this URL?

The URL is in the $flowExecutionUrl variable that the views are populated 
with.

>Or should I rather implement the SPNEGO logic in a separate
>servlet and let the flow do an external authentication
>using this servlet, similar as the X509 flow does?

I don't know that it's physically possible to implement it in a web flow, 
and I probably wouldn't be able to answer that question until I saw the 
working interaction.

But I do know that the only way to do it inside a flow would be to issue 
the 401s as part of a view state, otherwise it just won't work.

-- Scott



More information about the dev mailing list