Quantcast
Channel: Security
Viewing all articles
Browse latest Browse all 4737

ClaimsIdentity.FindFirst does not find claims

$
0
0

I  am attempting to write a single sign authentication/authorization MVC web application that authenticates a user from client application(s)  using OWIN and  Thinktecture.IdentityServer3.  I am creating claims in the authentication server in the following class:

using System; 
using System.Collections.Generic; 
using System.Linq; 
using System.Security.Claims; 
using System.Text; 
using System.Threading.Tasks; 
using IdentityServer3.Core; 
using IdentityServer3.Core.Extensions; 
using IdentityServer3.Core.Models;
using IdentityServer3.Core.Services; 
using IdentityServer3.Core.Services.Default;
using BioAppsIdentityServer.Respositories;
using BioAppsIdentityServer.Data_Models;
using Avion.Cryptography;

namespace BioAppsIdentityServer
{
    public class LocalRegistrationUserService : UserServiceBase
    {
        private static IUnitOfWork _uow; 
        public LocalRegistrationUserService(IUnitOfWork uow)
        {
            _uow = uow;
        }
        public class BioUser
        { 
            public string Subject { get; set; } 
            public string Username { get; set; } 
            public string Password { get; set; } 
            public List<Claim> Claims { get; set; } 
        }

        public static List<BioUser> Users { get { return GetLocalUsers(); } }
        public override Task AuthenticateLocalAsync(LocalAuthenticationContext context)
        {
            var user = Users.SingleOrDefault(x => x.Username == context.UserName && PasswordHasher.VerifyPassword(context.Password,x.Password));
            if (user != null)
            {
                context.AuthenticateResult = new AuthenticateResult(user.Subject, user.Username);
            }
            return Task.FromResult(0);
        }

        public override Task GetProfileDataAsync(ProfileDataRequestContext context)
        { 
             // issue the claims for the user 
            // var user = Users.SingleOrDefault(x => x.Subject == context.Subject.GetSubjectId()); 
            // if (user != null) 
            // { 
            //     context.IssuedClaims = user.Claims.Where(x => context.RequestedClaimTypes.Contains(x.Type)); 
            // } 
            return Task.FromResult(0); 
        } 

        private static List<BioUser> GetLocalUsers()
        {
            List<BioUser> listUsers = new List<BioUser>();
            foreach (VUSER usr in _uow.Repository<VUSER>().GetAll())
            {
                List<Claim> userClaims = new List<Claim>();
                BioUser memUser = new BioUser();
                memUser.Username = usr.EMAILADDRESS;
                memUser.Password = usr.PASSWORD;
                memUser.Subject = usr.USERID.ToString();
                userClaims.Add(new Claim(Constants.ClaimTypes.GivenName, usr.FIRSTNAME));
                userClaims.Add(new Claim(Constants.ClaimTypes.FamilyName, usr.LASTNAME));
                userClaims.Add(new Claim(Constants.ClaimTypes.Email, usr.EMAILADDRESS));
                if (string.IsNullOrWhiteSpace(usr.MIDDLENAME))
                {
                    userClaims.Add(new Claim(Constants.ClaimTypes.MiddleName, string.Empty));
                }
                else
                {
                    userClaims.Add(new Claim(Constants.ClaimTypes.MiddleName, usr.MIDDLENAME));
                }
                memUser.Claims = userClaims;
                listUsers.Add(memUser);
            }
            return listUsers;
        }
    }
}

After authentication the claims are processed on the client in the following Startup class

using Microsoft.IdentityModel.Protocols;
using Microsoft.Owin;
using Microsoft.Owin.Security;
using Microsoft.Owin.Security.Cookies;
//using Microsoft.Owin.Security.Google;
using Microsoft.Owin.Security.OpenIdConnect;
using Owin;
using System;
using System.Collections.Generic;
using System.IdentityModel;
using System.IdentityModel.Tokens;
using System.Security.Cryptography.X509Certificates;
using System.Linq;
using System.Web.Helpers;
using Thinktecture.IdentityModel.Client;
using System.Threading.Tasks;
using System.Security.Claims;

[assembly: OwinStartup(typeof(BioAppsIdentityClient.Startup))]

namespace BioAppsIdentityClient
{
    public class Startup
    {
        public void Configuration(IAppBuilder app)
        {
            app.UseCookieAuthentication(new CookieAuthenticationOptions
            {
                AuthenticationType = "Cookies"
            });

            app.UseOpenIdConnectAuthentication(new OpenIdConnectAuthenticationOptions
            {
                Authority = "https://localhost:44355/core",
                ClientId = "bioapp",
                RedirectUri = "https://localhost:44307/",
                ResponseType = "id_token",
                SignInAsAuthenticationType = "Cookies",
                UseTokenLifetime = false,

                Notifications = new OpenIdConnectAuthenticationNotifications
                {
                    SecurityTokenValidated = n =>
                    {
                        ClaimsIdentity id = n.AuthenticationTicket.Identity;
                        // we want to keep first name, last name, subject and roles
                        Claim givenName = id.FindFirst(JwtClaimTypes.GivenName);
                        Claim familyName = id.FindFirst(JwtClaimTypes.FamilyName);
                        Claim sub = id.FindFirst(JwtClaimTypes.Subject);
                        IEnumerable<Claim> roles = id.FindAll(JwtClaimTypes.Role);

                        // create new identity and set name and role claim type
                        ClaimsIdentity nid = new ClaimsIdentity(
                            n.AuthenticationTicket.Identity.AuthenticationType,
                            JwtClaimTypes.GivenName,
                            JwtClaimTypes.Role);

                       
                        // keep the id_token for logout
                        nid.AddClaim(new Claim("id_token", n.ProtocolMessage.IdToken));

                        nid.AddClaim(givenName);
                        nid.AddClaim(familyName);
                        nid.AddClaim(sub);
                        nid.AddClaims(roles);

                        n.AuthenticationTicket = new AuthenticationTicket(
                            nid,
                            n.AuthenticationTicket.Properties);

                        return Task.FromResult(0);
                    }
                }

            });
        }
    }
}

After the call to the server the ClaimsIdentity object is not null and appears to contain the GivenName claim ("given_name"). However the

Claim givenName = id.FindFirst(JwtClaimTypes.GivenName);

returns a null.   All the ClaimsIdentity.FindFirst commands return a null. When  I breakpoint and inspect the Clamindentity object I can see the claims "given_name" and the other claims in the ClaimIdentity object.

 


Viewing all articles
Browse latest Browse all 4737

Trending Articles



<script src="https://jsc.adskeeper.com/r/s/rssing.com.1596347.js" async> </script>