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