I have a web application that utilizes our organization's CAS servers for authentication. I am currently developing an integration with DocuSign for this application. A user will first come to our site and sign in with CAS. Then, they can go to the DocuSign area of the application, sign in to DocuSign, and then perform some functions tied to the DocuSign API. Each of these pieces works properly within my application.
My current problem is that I cannot access both Identities within the HttpContext simultaneously. I need the CAS Identity to determine user behavior and access to certain functions. I need the DocuSign Identity to get the necessary values to enable the API calls. In Startup.cs
services.AddAuthentication(CookieAuthenticationDefaults.AuthenticationScheme)
.AddCookie(options =>
{
options.LoginPath = new PathString("/Account/Login");
})
.AddCAS(options =>
{
options.CasServerUrlBase = Configuration["CasBaseUrl"];
options.SignInScheme = CookieAuthenticationDefaults.AuthenticationScheme;
})
.AddOAuth("DocuSign", options ->
{
//necessary DocuSign options
});
I have a HomeController that uses the Authorize attribute and properly requires CAS to access. I can properly access the claims from the CAS Identity. I have a DocusignController where I use Authorize(AuthenticationSchemes = "DocuSign"). An ActionFilter that applies to this controller shows that the DocuSign Identity is coming through properly. Unfortunately, the CAS Identity is not attached, so I cannot check for things such as admin permissions. I examined the cookies, and saw that the .AspNetCore.Cookies value changes when I go between the different Authentication Schemes.
One attempt at a solution was to change the DocusignController to have Authorize(AuthenticationSchemes = "DocuSign, CAS" as its attribute. This seems to be an 'or' rather than an 'and' of the two schemes. If CAS was the most recent scheme, then the CAS Identity is the one seen in my ActionFilter. Same for DocuSign.
Another attempt was to create my own AuthenticationHandler to combine the two Identities. Appended to the AddAuthentication above:
.AddScheme<CombinedSchemeOptions, CombinedHandler>
("Combined", op => { });
Then, within this CombinedHandler:
protected async override Task<AuthenticateResult> HandleAuthenticateAsync()
{
var CasResult = await Context.AuthenticateAsync("CAS");
if(CasResult?.Principal != null)
{
principal.AddIdentities(CasResult.Principal.Identities);
}
var DSResult = await Context.AuthenticateAsync("DocuSign");
if(DSResult?.Principal != null)
{
principal.AddIdentities(DSResult.Principal.Identities);
}
var ticket = new AuthenticationTicket(principal, "Combined");
return AuthenticateResult.Success(ticket);
}
This seems to behave the same way as before. The most recent Scheme I've used, upon entering the Combined scheme, will give a successful Result with an Identity, and the other Result will return with a failed result.
Is it possible for me to have these two Identities within the HttpContext.User simultaneously? Is it otherwise possible for me to combine claims from the two Identities into one and pass that along?