Claims Auth - .ASPXAUTH cookie remains
I created a custom SecurityTokenServiceHttpHandler to handle requests for authentication through Azure Active Directory. It works fine for most cases, but definitely gets wonky in some spots.
The main issue I'm having has been narroed down to the presence of .ASPXAUTH. When SetAuthCookie is called, it's creating the FedAuth tokens and unfortunately the ASPXAUTH token as well, which I believe is used for "persist my login" via the normal case.
The cookie itself is not cleared through SecurityManager's logout features (Logoff, DeleteAuthCookies).
The major side effect of not being able to kill this cookie is that a redirect loop is eventually caused by the presence of an ASPXAUTH cookie, telling the authentication end point you're OK, but having invalid FedAuth tokens. The claims service will keep routing to the ProcessRequest, which will fall through to "normal behavior" and try to route to the return uri, where the user is unauthorized to go (Permissions set to only authenticated users), then back to claims service and so forth.
1. Is there a way to set the auth cookie without the login persistence cookie?
2. Is this expected behavor?
My logout is now:
LogoutLink.Click += (sender, args) =>
// Meh.
FormsAuthentication.SignOut();
SecurityManager.Logout();
SecurityManager.DeleteAuthCookies();
InitializePanel(ClaimsManager.GetCurrentIdentity());
// Redirect to the current URL and let Sitefinity throw it to the unauthorized page.
Context.Response.Redirect( Context.Request.Url.AbsoluteUri, true);
;
Note, I now catch the case in ProcessRequest to prevent the described scenario, but again it feels heavy handed.
public
override
void
ProcessRequest(System.Web.HttpContext context)
// ...
// If they're hitting the login service after the system considers them auth'd, log them out. There's a
// real solid chance that the claims aren't properly aligned and the user is going to be redirected infinitely.
if
(context.User.Identity.IsAuthenticated)
SecurityManager.Logout();
SecurityManager.DeleteAuthCookies();
if
(!String.IsNullOrWhiteSpace(context.Request.QueryString[
"code"
]))
// Do secure AAD token grabbin'.
// Redirect back to the claims service, which will mark the user as authenticated and route to the return URI.
RedirectToClaimsService(context);
base
.ProcessRequest(context);
Hello Xian. Were you able to resolve the issue with the redirect loop?
I am facing a similar issue where I configured my SF app to use an external STS. I am seeing a redirect loop after the STS authenticates the user, generates the security token, and then redirects user back to the SF app: At this point the SF app does allow the user in but instead sends another request to the STS. And there the endless redirect loop begins.
Hi Xian. I want to experiment with your workaround: can you give me details on how to override the ProcessRequest method shown in your example code? I assume it's somewhere in login code of the SF app. Note that I'm new to Sitefinity.
My final solution was not much different than what you see above. Inside the block where I have captured a successful authentication, I set the current user via something like this:
var currentUser = UserUtil.GetUserByAzureId(objectId);
if
(currentUser !=
null
)
var vals = context.Request.RequestContext.RouteData.Values;
var service = ((
string
)vals[
"Service"
]).ToLower();
SetAuthCookie(currentUser);
var reqMessage = RequestMessage.Empty;
SendToken(context, currentUser, reqMessage, service);
// This stores the ObjectId from the successful claim or auth code retrieval.
AzureRequestManager.ObjectIdentifier =
null
;
RedirectToService(context);
Redirect to service looks like:
private
static
void
RedirectToService(HttpContext context)
const
string
ServiceUrl =
"~/"
+ Constants.LocalService +
"/SWT"
;
var serviceUrl = ServiceUrl + (!ServiceUrl.Contains(
"?"
) ?
"?"
:
"&"
);
var realm = context.Server.UrlEncode(context.Request.Url.GetLeftPart(UriPartial.Authority));
serviceUrl = serviceUrl +
"realm="
+ realm +
"&redirect_uri="
+ context.Server.UrlEncode(PageUtil.GetHomePageUrl()) +
"&redirect_url_failure="
+ context.Server.UrlEncode(context.Request.Url.AbsoluteUri);
context.Response.Redirect(serviceUrl);
If you've set your token and auth cookie, the next time you direct your request to the service, it'll register the claim properly.
Also worth noting, the Logout code above is about the same as well, barring some different redirects.
Thx Xian! I want to experiment with your workaround: Can you give me details on how/where to override the ProcessRequest method shown in your example code? I assume it's somewhere in login code of the SF app. Note that I'm new to Sitefinity.
Hi Xian.
Here's a concrete example: I'm experimenting with the following SF app from the SF SDK github.com/.../Telerik.Sitefinity.Samples.Quantum
I was able to configure this app to use my external STS. Currently the flow is as follows:
User --> SF app --> User logs in with username/pwd --> User clicks submit, is redirected to My STS --> My STS generates token --> Redirect back to SF app --> User is logged in
I want to tweak the SF app some more so the follows becomes:
User --> SF app --> User is redirected to My STS --> My STS generates token --> Redirect back to SF app --> User is logged in
Can you help me figure out the tweaks needed in this SF app? I think it may be as simple as modifying the Login widget.The way to accomplish the hook is all described in here: github.com/.../Sitefinity-External-STS-Integration
I'd suggest setting up this code as outlined in the readme and stepping through it to get comfortable.
I am under NDA for a few aspects of the authentication that will go any deeper than this, so I'd just urge you to review the sample.