Asked by:
IsInRole Only Works on Local

Question
-
User-1126840064 posted
Looking to leverage Azure Web Apps & Azure Active Directory, Application Registration Roles security model using Web Forms.
When I publish to Azure Apps Service the IsInRole function is always resulting as false. It works fine from my local.
I created a gridview and bound the claims info to it and the claim does show the the expected role even when run from the app service.
Additionally when run from local the issuer results as https://sts.windows.net/<Azure Tenant ID>/ whereas when published it results as Local Authority.
Interestingly enough I observed that when running from local it's creating entries in the UserTokenCahes table but not when running from the published site.
What am I missing?
Monday, December 16, 2019 6:11 PM
All replies
-
User-719153870 posted
Hi kris.kawaguchi,
Looking to leverage Azure Web Apps & Azure Active Directory, Application Registration Roles security model using Web Forms.How you achieve the authentication with Azure Active Directory? Is it a built-in authentication of Azure Web Apps or some other 3rd party login?
Best Regard,
Yang Shen
Tuesday, December 17, 2019 7:57 AM -
User-1126840064 posted
its built in authentication for Azure Web Apps
using System; using System.Collections.Generic; using System.Configuration; using System.Globalization; using System.IdentityModel.Claims; using System.Linq; using System.Threading.Tasks; using System.Web; using Microsoft.IdentityModel.Clients.ActiveDirectory; using Microsoft.Owin.Extensions; using Microsoft.Owin.Security; using Microsoft.Owin.Security.Cookies; using Microsoft.Owin.Security.OpenIdConnect; using Owin; using KrisTennant.Models; using System.IdentityModel.Tokens.Jwt; using System.IdentityModel; using Microsoft.IdentityModel.Tokens; namespace KrisTennant { public partial class Startup { private static string clientId = ConfigurationManager.AppSettings["ida:ClientId"]; private static string appKey = ConfigurationManager.AppSettings["ida:ClientSecret"]; private static string aadInstance = EnsureTrailingSlash(ConfigurationManager.AppSettings["ida:AADInstance"]); private static string tenantId = ConfigurationManager.AppSettings["ida:TenantId"]; private static string postLogoutRedirectUri = ConfigurationManager.AppSettings["ida:PostLogoutRedirectUri"]; private string authority = aadInstance + tenantId; // This is the resource ID of the AAD Graph API. We'll need this to request a token to call the Graph API. private static string graphResourceId = "https://graph.windows.net"; public void ConfigureAuth(IAppBuilder app) { app.SetDefaultSignInAsAuthenticationType(CookieAuthenticationDefaults.AuthenticationType); app.UseCookieAuthentication(new CookieAuthenticationOptions()); app.UseOpenIdConnectAuthentication( new OpenIdConnectAuthenticationOptions { ClientId = clientId, Authority = authority, PostLogoutRedirectUri = postLogoutRedirectUri, TokenValidationParameters = new TokenValidationParameters() { // map the claimsPrincipal's roles to the roles claim RoleClaimType = System.Security.Claims.ClaimTypes.Role }, Notifications = new OpenIdConnectAuthenticationNotifications() { // // If there is a code in the OpenID Connect response, redeem it for an access token and refresh token, and store those away. // AuthorizationCodeReceived = (context) => { var code = context.Code; ClientCredential credential = new ClientCredential(clientId, appKey); string signedInUserID = context.AuthenticationTicket.Identity.FindFirst(ClaimTypes.NameIdentifier).Value; AuthenticationContext authContext = new AuthenticationContext(authority, new ADALTokenCache(signedInUserID)); AuthenticationResult result = authContext.AcquireTokenByAuthorizationCodeAsync( code, new Uri(HttpContext.Current.Request.Url.GetLeftPart(UriPartial.Path)), credential, graphResourceId).Result; return Task.FromResult(0); } } } ); // This makes any middleware defined above this line run before the Authorization rule is applied in web.config app.UseStageMarker(PipelineStage.Authenticate); } private static string EnsureTrailingSlash(string value) { if (value == null) { value = string.Empty; } if (!value.EndsWith("/", StringComparison.Ordinal)) { return value + "/"; } return value; } } }
Tuesday, December 17, 2019 4:23 PM -
User-719153870 posted
Hi kris.kawaguchi,
Seems the problem is after you published to Azure Apps Service, it couldn't fill the role information to user.
Please check where you get the role information and how you fill it to user claim.
Best Regard,
Yang Shen
Thursday, December 19, 2019 8:06 AM -
User-1126840064 posted
Claims appears to be coming in fine
Published does not work
Local works fine
Thursday, December 19, 2019 9:52 PM -
User-719153870 posted
Hi kris.kawaguchi,
As you can see from these two screen shots, in local the Type is called "http.../../../role" while in the published one it's called "roles".
It's unknown why this role type got changed but you can try to add below code to your program to force reading the "roles" instead of "http.../../../role" after you published it:
TokenValidationParameters = new TokenValidationParameters { RoleClaimType = "roles", },
Best Regard,
Yang Shen
Friday, December 20, 2019 1:39 AM -
User-1126840064 posted
Gave it a go but no luck. Any recommendations on how to approach trouble shooting why the claims are resulting differently?
Friday, December 20, 2019 3:22 AM -
User-719153870 posted
Hi kris.kawaguchi,
kris.kawaguchi
Any recommendations on how to approach trouble shooting why the claims are resulting differently?Sorry, I'm not sure how to trouble shooting it. However, i can suggest another workaround which please check Efficiently check role claim.
In your case, you could use below code to replace the built-in IsInRole method:
((System.Security.Claims.ClaimsIdentity)User.Identity).HasClaim("roles", "Admin3")
Hope this could help.
Best Regard,
Yang Shen
Friday, December 20, 2019 6:44 AM