locked
Authorization roles WebAPI oauth owin not working RRS feed

  • Question

  • User1851741870 posted

    I've recently joined a project team and have been tasked with setting up User Roles for the backend of the project. It uses ASP.NET C# WebApi with Owin. My issue is, when I assign an attribute to the Controller Method like this:

    [Authorize(Roles = "Admin")]

    The response is always Authorization denied for this request. However if I simply use:

    [Authorize]

    public class ApplicationOAuthProvider : OAuthAuthorizationServerProvider
        {
            private readonly string _publicClientId;
            
            //Declare an instance for log4net
            private static readonly ILog Log =
                  LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);
    
            public ApplicationOAuthProvider(string publicClientId)
            {
                if (publicClientId == null)
                {
                    throw new ArgumentNullException("publicClientId");
                }
    
                _publicClientId = publicClientId;
            }
    
            public override async Task GrantResourceOwnerCredentials(OAuthGrantResourceOwnerCredentialsContext context)
            {
                try
                {
                    ClyBayEntities clyBayEntitiesContext = new ClyBayEntities();
                    UserFunctions userFunctions = new UserFunctions();
                    // here we check whether the username and pasword is valid
    
                    var userManager = context.OwinContext.GetUserManager<ApplicationUserManager>();
                    
                    ApplicationUser user = await userManager.FindAsync(RijndaelEncryption.Encrypt(context.UserName.Trim()), context.Password);
    
                    if (user == null)
                    {
                        Log.Info(" user == null :::  The user name and / or password is incorrect.");
                        context.SetError("invalid_grant", "The user name and/or password is incorrect.");
                        return;
                    }
    
                    if (user!=null && user.LockoutEnabled==true)
                    {
                        Log.Info(" user exist :::  but user is lockout");
                        context.SetError("invalid_grant", "The user name and/or password is incorrect.");
                        return;
                    }
    
                    if (!userManager.IsPhoneNumberConfirmed(user.Id))
                    {
                        context.SetError("invalid_grant", "Please Confirm Your Phone Number! Number Is Not Verified Yet");
                        return;
                    }
                    
    
                    // Get the userdetails from the db
                    User userDetails = clyBayEntitiesContext.Users.FirstOrDefault(x => x.AspNetUserId == user.Id);
                    if (userDetails.IsDeleted == true)
                    {
                        Log.Info(" user exist :::  but IsDeleted value is true");
                        context.SetError("invalid_grant", "The user name and/or password is incorrect.");
                        return;
                    }
                    // mod: tur461
                    var r = await userManager.GetRolesAsync(user.Id);
                    string Role = r.Take(1).SingleOrDefault();
    
                    if (userDetails.VerificationStatus == false)
                        {
                            //context.SetError("invalid_grant", "Your Account has been suspended. Please contact Administrator.");
                        context.SetError("invalid_grant", "Please contact admin to verify.");
                        return;
                        }
    
    
                    // Here create an identity for the requesting user
                    ClaimsIdentity identity = new ClaimsIdentity(context.Options.AuthenticationType);
                                    identity.AddClaim(new Claim(ClaimTypes.Name, context.UserName));
                                    identity.AddClaim(new Claim("UserId", userDetails.AspNetUserId.ToString()));
                                    identity.AddClaim(new Claim("Id", userDetails.ID.ToString()));
                                   // identity.AddClaim(new Claim("EmailId", "Email Not Defined"));//userDetails.Email
                    identity.AddClaim(new Claim("Name", userDetails.Name.ToString()));
                                    identity.AddClaim(new Claim("PhoneNumber", userDetails.PhoneNo.ToString()));
                                    identity.AddClaim(new Claim("RoleName", Role));
    
                    
                    AuthenticationProperties properties = CreateProperties(Role);
                    AuthenticationTicket ticket = new AuthenticationTicket(identity, properties);
    
                    context.Validated(ticket);
    
    
                    userFunctions.SaveLoginActivity(userDetails.ID);
                        //.Info(" identity ::: " + identity);
                        return;
    
                }
                catch (Exception ex)
                {
                    Log.Error("Start log ERROR..." + ex);
                    throw;
                }
    
            }
    
            public override Task TokenEndpoint(OAuthTokenEndpointContext context)
            {
                foreach (KeyValuePair<string, string> property in context.Properties.Dictionary)
                {
                    Log.Info(" KeyValuePair ::: " + property.Key + " ::: " + property.Value);
                    context.AdditionalResponseParameters.Add(property.Key, property.Value);
                }
    
                return Task.FromResult<object>(null);
            }
    
            public override Task ValidateClientAuthentication(OAuthValidateClientAuthenticationContext context)
            {
                // Resource owner password credentials does not provide a client ID.
                if (context.ClientId == null)
                {
                    context.Validated();
                }
    
                return Task.FromResult<object>(null);
            }
    
            public override Task ValidateClientRedirectUri(OAuthValidateClientRedirectUriContext context)
            {
                if (context.ClientId == _publicClientId)
                {
                    Uri expectedRootUri = new Uri(context.Request.Uri, "/");
    
                    if (expectedRootUri.AbsoluteUri == context.RedirectUri)
                    {
                        context.Validated();
                    }
                }
    
                return Task.FromResult<object>(null);
            }
    
            public static AuthenticationProperties CreateProperties(string roleName)
            {
                IDictionary<string, string> data = new Dictionary<string, string>
                {
                    { "Role", roleName }
                    //{"doi", DateTime.Now. }
                };
                return new AuthenticationProperties(data);
            }
    
    
        }
    
    Saturday, November 7, 2020 5:05 PM

All replies

  • User753101303 posted

    Hi,

    What iif you start with something such a::

     identity.AddClaim(new Claim(identiy.RoleClaimType,"Admin")); // instead of "RoleName"

    The Authorize attribute should use the same property so that it can get check role claims regardless of how they are named by this particular identity.

    Friday, May 28, 2021 2:19 PM