question

EdBrinkman-1115 avatar image
0 Votes"
EdBrinkman-1115 asked ·

Authentication ticket value is null in the AuthorizationCodeReceived event

I have been able to login to the identity provider, and get the access_token. My problem is with mapping the OpenID connect groups to roles. I am changing an MVC 4 website. The article post at ( https://developer.okta.com/blog/2018/04/18/authorization-in-your-aspnet-mvc-4-application ) gives a sample code for AuthorizationCodeReceived. The problem is that the Authentication ticket value is null in the AuthorizationCodeReceived event. . The article states that mapping the OpenIDConnect groups to roles is required to get authorization attributes to work. My website is not using Azure Active Directory. Do you have any advice?

dotnet-aspnet-mvcazure-ad-openid-connect
10 |1000 characters needed characters left characters exceeded

Up to 10 attachments (including images) can be used with a maximum of 3.0 MiB each and 30.0 MiB total.

EdBrinkman-1115 avatar image
0 Votes"
EdBrinkman-1115 answered ·

I found a post that fixed the problem. The authentication works now. I wanted to post it for any future reference. https://stackoverflow.com/questions/20737578/asp-net-sessionid-owin-cookies-do-not-send-to-browser

·
10 |1000 characters needed characters left characters exceeded

Up to 10 attachments (including images) can be used with a maximum of 3.0 MiB each and 30.0 MiB total.

YijingSun-MSFT avatar image
0 Votes"
YijingSun-MSFT answered ·

Hi @EdBrinkman-1115,

As far as I think,you are unnecessary to use Azure Active Directory with OpenID connect if you have other third party such as facebook, google.
You need to configure like AAD and send notification.And then you need to wait returning a result.
You could refer to below articles:
Tutorial: Add sign-in to Microsoft to an ASP.NET web app

AuthorizationCodeReceived


If the answer is helpful, please click "Accept Answer" and upvote it.

Note: Please follow the steps in our  documentation  to enable e-mail notifications if you want to receive the related email notification for this thread.


Best regards,
Yijing Sun

·
10 |1000 characters needed characters left characters exceeded

Up to 10 attachments (including images) can be used with a maximum of 3.0 MiB each and 30.0 MiB total.

EdBrinkman-1115 avatar image
0 Votes"
EdBrinkman-1115 answered ·

I can sign in and get an access token. The authorization code received event does fire. The n.AuthenticationTicket is null

The identity provider is setup to use the scope "openid profile ismemberof".

Other posts talk about using a hybrid flow with scope values of "code id_token" for access tokens.

I have not found an explanation.

· 1 ·
10 |1000 characters needed characters left characters exceeded

Up to 10 attachments (including images) can be used with a maximum of 3.0 MiB each and 30.0 MiB total.

Hi @EdBrinkman-1115,
If you need to use OpenId connect hybrid flow,it's need Identity Server. Do you care of using AAD? If you don't care,you could refer to below article.

0 Votes 0 ·
EdBrinkman-1115 avatar image
0 Votes"
EdBrinkman-1115 answered ·

My company is using the using the authorization code flow with PKCE. I still learning the technology. I have been grabbing pieces of code. My current problem does not give me any diagnostic information. I have been working off the code at https://www.scottbrady91.com/ASPNET/Refreshing-your-Legacy-ASPNET-IdentityServer-Client-Applications

Another article at https://developer.okta.com/blog/2018/04/18/authorization-in-your-aspnet-mvc-4-application talks about using allowed grant types of Authorization Code, Implicit (Hybrid) - Allow ID Token. Both articles reference the authentication ticket property of the AurhorizationCodeReceivedNotification parameter. The authentication ticket property is null. So the code does not work. I do not know enough about the technology to know why.

The SecurityTokenValidatedEvent is not firing either. I do not know why. An incoming id_token is to be parsed, validated, and used to populate context.AuthenticationTicket with a ClaimsIdentity whose claims come from the incoming token according to the text "Modern Authentication with Azure Active Directory for Web Applications".

· 1 ·
10 |1000 characters needed characters left characters exceeded

Up to 10 attachments (including images) can be used with a maximum of 3.0 MiB each and 30.0 MiB total.

Hi @EdBrinkman-1115 ,
Do you have enabled SSL for returned URL?It maybe the result of not firing SecurityTokenValidatedEvent.

0 Votes 0 ·
EdBrinkman-1115 avatar image
0 Votes"
EdBrinkman-1115 answered ·

No, the returned URL is http://localhost/xxxx. SSL is not enabled for the website.
PKCE has been turned off temporarily.
I have run code but the authorize attribute is not working. The variable filterContext.HttpContext.User.Identity.IsAuthenticated returns false. The Identity name is null. The identity is a generic identity.
I did find that the variable User.Claims is populated correctly. User.IsAuthenticated returns true. However, User.Identity.Name is null.
The problem is that the authorize attribute is not working. My code does not match the articles I have been working from. Below is the code I cannot get to work because the variable n.AuthenticationTicket is null.

//scott brady code
var id = new ClaimsIdentity(n.AuthenticationTicket.Identity.AuthenticationType);
id.AddClaims(userInfoResponse.Claims);
id.AddClaim(new Claim("access_token", tokenResponse.AccessToken));
id.AddClaim(new Claim("id_token", n.ProtocolMessage.IdToken));

                 n.AuthenticationTicket = new AuthenticationTicket(
                     new ClaimsIdentity(id.Claims, n.AuthenticationTicket.Identity.AuthenticationType),
                     n.AuthenticationTicket.Properties);

//OKTA site code
foreach(var group in userInfoResponse.Claims.Where(x => x.Type == "groups"))
{
n.AuthenticationTicket.Identity.AddClaim(new Claim(ClaimTypes.Role, group.Value));
}

· 1 ·
10 |1000 characters needed characters left characters exceeded

Up to 10 attachments (including images) can be used with a maximum of 3.0 MiB each and 30.0 MiB total.

Hi @EdBrinkman-1115 ,
Is it possible you have the wrong Authorize?And if you're doing Owin, then you don't need the WebHost library.

0 Votes 0 ·
EdBrinkman-1115 avatar image
0 Votes"
EdBrinkman-1115 answered ·

The website does not have a webhost library reference.

· 1 ·
10 |1000 characters needed characters left characters exceeded

Up to 10 attachments (including images) can be used with a maximum of 3.0 MiB each and 30.0 MiB total.

Hi @EdBrinkman-1115 ,
the problem of User.Identity.Name is null may is that you don't set NameClaimType in OpenIdConnectOptions. You need to debug and check which lines have errors.

0 Votes 0 ·
EdBrinkman-1115 avatar image
0 Votes"
EdBrinkman-1115 answered ·

How do I determine which lines have errors? No exceptions are thrown in the startup.cs file. I added a application_error event handler to the global_asax file also.

I tried setting the NameClaimType inOpenIdConnectOptions to "name". It did not work. Is that the correct value to use? I also tried "http://schemas.xmlsoap.org/ws/2005/05/identity/claims/nameidentifier" That value did not work either.

I added a coworker's code to the MessageReceived event. Now the AuthorizationCodeReceived event does not fire. However, in the event SecurityTokenValidated the variable notification.AuthenticationTicket.Identity.Name is correct and the variable notification.AuthenticationTicket.Identity.IsAuthenticated returns true. I add the claims that include the role because the claims do not include the role claim value. No errors are thrown. It looks like the authentication works in the startup class file but does not flow to the controllers. I do not know why.

Nothing has improved. The variable Request.IsAuthenticated returns false. The variable HttpContext.GetOwinContext().Authentication.User.Identity.Name is an empty string. The variable User.Identity.Name is an empty string.

context.ProtocolMessage.Code = null;
context.ProtocolMessage.IdToken = idToken.ToString();
context.ProtocolMessage.AccessToken = accessToken.ToString();

·
10 |1000 characters needed characters left characters exceeded

Up to 10 attachments (including images) can be used with a maximum of 3.0 MiB each and 30.0 MiB total.

EdBrinkman-1115 avatar image
0 Votes"
EdBrinkman-1115 answered ·

I have made some progress but the Authorize attribute will not work. The variable filterContext.HttpContext.User.Identity.IsAuthenticated in the custom authorize attribute returns false. How can the variables HttpContext.GetOwinContext().Authentication and User.Identity.Name be correct in the controller but the authorize attribute does not work?
Both the Authorize and custom Authorize attribute do not work. They treat the user as unauthenticated.

The begin request event in global asax and custom authentication fire before the OWIN AuthorizationCodeReceived event. I have found that the OWIN context does not exist without a request, and the Startup class only runs once for the application, not for each request. Your Startup class should initialize your middleware and your application and the middleware and the application should access the OWIN context when needed.

·
10 |1000 characters needed characters left characters exceeded

Up to 10 attachments (including images) can be used with a maximum of 3.0 MiB each and 30.0 MiB total.

EdBrinkman-1115 avatar image
0 Votes"
EdBrinkman-1115 answered ·

Would this problem be fixed if an authentication ticket was issued by the external identity provider? Can the authorize attribute work with OWIN open id connect?

Right now I am attempting to use global.asax begin request to set the principal and roles.

· 1 ·
10 |1000 characters needed characters left characters exceeded

Up to 10 attachments (including images) can be used with a maximum of 3.0 MiB each and 30.0 MiB total.

Hi @EdBrinkman-1115 ,
Yes,you need to provide an authentication ticket.Because of the use of the [Authorize] attribute, all methods of this controller can be executed only if the user is authenticated. If the user isn't authenticated and tries to access the controller, OWIN initiates an authentication challenge and forces the user to authenticate.
I think,you need to learn more about AAD.

0 Votes 0 ·
EdBrinkman-1115 avatar image
0 Votes"
EdBrinkman-1115 answered ·

Please stop referencing the same article. I need an answer to my original question. My code does not work. My employer is making me use the authorization_code response not the response id_token. I do not know if that is a big factor. I am creating an authentication ticket and assigning it to n.AuthenticationTicket in the AuthorizationCodeReceived event. Below is my code. It is not working. That is why I opened this question. I have seen a lot on AAD. I found an article at https://leastprivilege.com/2016/08/21/why-does-my-authorize-attribute-not-work/ . I suspect there is a setup problem because no authentication ticket exists coming in to the event. The authentication ticket constructor takes in n.AuthenticationTicket.Properties which is null also so I had to hard code something. I am sure it is not correct. I have also seen code samples at https://brockallen.com/2013/10/24/a-primer-on-owin-cookie-authentication-middleware-for-the-asp-net-developer/ . Is there an authoritative source? The link you provided does not cover creating AuthenticationTickets. The example uses id_token response type which is not available to me. I can only use a response type of authorization_code.

var id = new ClaimsIdentity();
id.AddClaims(decodedAccessTokenValue.Claims);
id.AddClaim(new Claim(System.Security.Claims.ClaimTypes.Name, userEmail));
id.AddClaim(new Claim(ClaimTypes.Role, "AmerenAdmin"));
id.AddClaim(new Claim("access_token", accessToken.ToString()));
id.AddClaim(new Claim("expires_at", DateTime.Now.AddSeconds(double.Parse(expiresIn.ToString())).ToLocalTime().ToString(CultureInfo.InvariantCulture)));
id.AddClaim(new Claim("id_token", idToken.ToString()));

                     n.AuthenticationTicket = new AuthenticationTicket(
                         new ClaimsIdentity(id.Claims, AuthenticationTypes.Password, "name", "role"),
                         new AuthenticationProperties { IsPersistent = true });
· 1 ·
10 |1000 characters needed characters left characters exceeded

Up to 10 attachments (including images) can be used with a maximum of 3.0 MiB each and 30.0 MiB total.

Hi @EdBrinkman-1115 ,

The link you provided does not cover creating AuthenticationTickets.

If authentication succeeds, the OIDC middleware creates an authentication ticket.And if you need to read more details of middleware,you could refer this:
https://docs.microsoft.com/en-us/azure/architecture/multitenant-identity/authenticate
0 Votes 0 ·