locked
IsInRole Only Works on Local RRS feed

  • 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

    x

    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