HI All, I am newbie, doing third party Authentication for the first time,
I am developing a .NET MVC project which contains also a .NET WebAPI endpoint, I have successfully integrated the single sign on following this guidelines:
- https://developer.okta.com/quickstart/#/okta-sign-in-page/dotnet/aspnet4
- https://github.com/okta/samples-aspnet
This is the authentication code I am using in the backend (I am using cookies as authentication approach):
public static void Configure(IAppBuilder app, IAppConfiguration appConfig)
{
app.SetDefaultSignInAsAuthenticationType(CookieAuthenticationDefaults.AuthenticationType);
app.UseCookieAuthentication(new CookieAuthenticationOptions
{
AuthenticationType = CookieAuthenticationDefaults.AuthenticationType
});
app.UseOpenIdConnectAuthentication(new OpenIdConnectAuthenticationOptions
{
ClientId = appConfig.OktaClientId,
ClientSecret = appConfig.OktaClientSecret,
Authority = appConfig.OktaIssuer,
RedirectUri = appConfig.OktaRedirectUri,
ResponseType = OpenIdConnectResponseType.CodeIdToken,
Scope = OpenIdConnectScope.OpenIdProfile,
PostLogoutRedirectUri = appConfig.OktaLogoutRedirectUri,
TokenValidationParameters = new TokenValidationParameters
{
NameClaimType = "name"
},
Notifications = new OpenIdConnectAuthenticationNotifications
{
AuthorizationCodeReceived = async n =>
{
var tokenClient = new TokenClient(appConfig.OktaOrganizationUri + "/v1/token", appConfig.OktaClientId, appConfig.OktaClientSecret);
var tokenResponse = await tokenClient.RequestAuthorizationCodeAsync(n.Code, appConfig.OktaRedirectUri).ConfigureAwait(false);
if (tokenResponse.IsError)
{
throw new AuthenticationException(tokenResponse.Error);
}
var userInfoClient = new UserInfoClient(appConfig.OktaOrganizationUri + "/v1/userinfo");
var userInfoResponse = await userInfoClient.GetAsync(tokenResponse.AccessToken).ConfigureAwait(false);
var identity = new ClaimsIdentity();
identity.AddClaims(userInfoResponse.Claims);
identity.AddClaim(new Claim("id_token", tokenResponse.IdentityToken));
identity.AddClaim(new Claim("access_token", tokenResponse.AccessToken));
if (!string.IsNullOrEmpty(tokenResponse.RefreshToken))
{
identity.AddClaim(new Claim("refresh_token", tokenResponse.RefreshToken));
}
var nameClaim = new Claim(ClaimTypes.Name, userInfoResponse.Claims.FirstOrDefault(c => c.Type == "name")?.Value);
identity.AddClaim(nameClaim);
n.AuthenticationTicket = new AuthenticationTicket(
new ClaimsIdentity(identity.Claims, n.AuthenticationTicket.Identity.AuthenticationType),
n.AuthenticationTicket.Properties);
},
RedirectToIdentityProvider = n =>
{
if (n.ProtocolMessage.RequestType == OpenIdConnectRequestType.Logout)
{
var idTokenClaim = n.OwinContext.Authentication.User.FindFirst("id_token");
if (idTokenClaim != null)
{
n.ProtocolMessage.IdTokenHint = idTokenClaim.Value;
}
}
return Task.CompletedTask;
}
}
});
}
My login action controller is as follows:
[Route("accounts"), Route("accounts/login")]
public ActionResult Login()
{
if (!HttpContext.User.Identity.IsAuthenticated)
{
HttpContext.GetOwinContext().Authentication.Challenge(OpenIdConnectAuthenticationDefaults.AuthenticationType);
return new HttpUnauthorizedResult();
}
if (HttpContext.Session["loggedUser"] == null)
{
var principal = HttpContext.GetOwinContext().Authentication.User;
HttpContext.Session["loggedUser"] = new OktaLoggedUser(principal);
}
return RedirectToAction("Index", "Installations");
}
However, in order to consume the API, I need get the access token from the Javascript code since the API controllers are authenticated if there is a valid Okta access token in the Authorization header:
ajax: {
url: "/resources",
type: "GET",
datatype: "json",
beforeSend: function (request) {
request.setRequestHeader("Auhtorization", OKTA_ACCESS_TOKEN);
},
}
I ignore if there is any okta javascript library I can use to get the access token or maybe the backend configuration I am using is wrong …
I gave a try to the Sign-in widget, but even after using the method setCookiesAndRedirect, the web request is not authenticated in the back-end …
Regards