0

How to use claims? For example, I want to set access to each page (resource) for each user. I understand, I can do it using roles, but as I understand, claim-based is more effectively. But when I try to create a claim, I see the following method:

        userIdentity.AddClaim(new Claim(ClaimTypes.Role, "test role"));

first parameter of constructor of Claim class get ClaimTypes enum, which has many "strange" members like Email, Phone etc. I want to set that this claim and then check this claim to have access to certain resource. I'm on wrong way? How to do it?

Oleg Sh
  • 8,496
  • 17
  • 89
  • 159
  • Claims are more general than roles. Check out my answer to this question http://stackoverflow.com/questions/29593214/claims-without-roles/29594321#29594321 – Wiktor Zychla Apr 27 '15 at 07:01

2 Answers2

1

From the code above, I am assuming you have already added the claim in startup class on authenticated of your provider as below.

context.Identity.AddClaim(new Claim("urn:google:name", context.Identity.FindFirstValue(ClaimTypes.Name))); // added claim for reading google name
context.Identity.AddClaim(new Claim("urn:google:email", context.Identity.FindFirstValue(ClaimTypes.Email))); // and email too

Once you have added the claims in startup, when the request is actually processed check if its a callback and if yes, read the claims as below(in IHttpHandler).

public void ProcessRequest(HttpContext context)
    {
        IAuthenticationManager authManager = context.GetOwinContext().Authentication;
        if (string.IsNullOrEmpty(context.Request.QueryString[CallBackKey]))
        {
            string providerName = context.Request.QueryString["provider"] ?? "Google";//I have multiple providers so checking if its google
            RedirectToProvider(context, authManager, providerName);
        }
        else
        {
            ExternalLoginCallback(context, authManager);
        }
    }

If its 1st call redirect to provider

private static void RedirectToProvider(HttpContext context, IAuthenticationManager authManager, string providerName)
    {
        var loginProviders = authManager.GetExternalAuthenticationTypes();

        var LoginProvider = loginProviders.Single(x => x.Caption == providerName);

        var properties = new AuthenticationProperties()
        {
            RedirectUri = String.Format("{0}&{1}=true", context.Request.Url, CallBackKey)
        };

        //string[] authTypes = { LoginProvider.AuthenticationType, DefaultAuthenticationTypes.ExternalCookie };
        authManager.Challenge(properties, LoginProvider.AuthenticationType);

        //without this it redirect to forms login page
        context.Response.SuppressFormsAuthenticationRedirect = true;
    }

And finally read the claims you get back

public void ExternalLoginCallback(HttpContext context, IAuthenticationManager authManager)
    {
        var loginInfo = authManager.GetExternalLoginInfo();
        if (loginInfo == null)
        {
            throw new System.Security.SecurityException("Failed to login");
        }

        var LoginProvider = loginInfo.Login.LoginProvider;
        var ExternalLoginConfirmation = loginInfo.DefaultUserName;

        var externalIdentity = authManager.GetExternalIdentityAsync(DefaultAuthenticationTypes.ExternalCookie);
        var emailClaim = externalIdentity.Result.Claims.FirstOrDefault(c => c.Type == ClaimTypes.Email);
        var email = emailClaim.Value;

        var pictureClaim = externalIdentity.Result.Claims.FirstOrDefault(c => c.Type.Equals("picture"));
        var pictureUrl = pictureClaim.Value;

        LogInByEmail(context, email, LoginProvider); //redirects to my method of adding claimed user as logged in, you will use yours.
    }
Chaitanya Gadkari
  • 2,669
  • 4
  • 30
  • 54
0

Claim doesn't set permission. It's used to verify you that "you are who you claim to be you are". These claims are identified by issuer, usually a 3rd party. See for example this article for description. So, you should define which claims are necessary (who user should be) in order to access a certain page. Otherwise, using claim-based authorization will be same as using identity based or role based.

Leo Y
  • 659
  • 7
  • 22
  • as I understand, I can set claims for user during auth and then validate has user claim to access for certain page or not. Can you show some code to access to certain page for logged user using claims ? – Oleg Sh Apr 25 '15 at 08:09