Reputation: 2967
I have set-up identityserver3 and MVC4 client using this tutorial. When I configured client to use 'Implicit' flow things are working as expected and I am getting back 'profile' scope. i.e. I can find claims first_name and given_name. Below my configuration code.
Client and User configuration
public static class Users
{
public static List<InMemoryUser> Get()
{
return new List<InMemoryUser>
{
new InMemoryUser
{
Username = "Bob",Password = "password",Subject = "1",
Claims = new []
{
new Claim(Constants.ClaimTypes.GivenName,"firstName"),
new Claim(Constants.ClaimTypes.FamilyName,"lastName")
}
}
};
}
}
public static class Clients
{
public static IEnumerable<Client> Get()
{
return new[]
{
new Client
{
ClientId = "MVC",
ClientName = "MVC Client Name",
RedirectUris = new List<string>
{
"https://localhost:44302/"
},
Flow = Flows.Implicit,
AllowAccessToAllScopes = true
}
};
}
}
Identity Server Configuration
public void Configuration(IAppBuilder app)
{
JwtSecurityTokenHandler.InboundClaimTypeMap = new Dictionary<string, string>();
app.Map("/identity", appBuilder => {
appBuilder.UseIdentityServer(new IdentityServer3.Core.Configuration.IdentityServerOptions
{
SiteName = "Site Name",
SigningCertificate = LoadCertificate(),
RequireSsl = false,
Factory = new IdentityServer3.Core.Configuration.IdentityServerServiceFactory()
.UseInMemoryClients(Clients.Get())
.UseInMemoryUsers(Users.Get())
.UseInMemoryScopes(StandardScopes.All)
});
});
app.UseCookieAuthentication(new Microsoft.Owin.Security.Cookies.CookieAuthenticationOptions
{
AuthenticationType = "Cookies"
});
app.UseOpenIdConnectAuthentication(new OpenIdConnectAuthenticationOptions
{
Authority = "https://localhost:44302/identity",
ClientId = "MVC",
RedirectUri = "https://localhost:44302/",
ResponseType = "id_token",
SignInAsAuthenticationType = "Cookies",
Scope = "openid profile"
});
}
In my MVC application I have secured Action on Home controller named 'Contact'
[Authorize]
public ActionResult Contact()
{
ClaimsPrincipal principal = User as ClaimsPrincipal;
return View(principal.Claims);
}
And finally here is simple view
@model IEnumerable<System.Security.Claims.Claim>
@foreach (var item in Model)
{
<div>
<span>@item.Type</span>
<span>@item.Value</span>
</div>
}
</div>
Now when I run this app, after clicking on secure 'Contact' link I am being redirected to STS server and after providing credentials I can see below output.
Note that claims given_name and family_name exists in the claims returned by STS.
Problem:
The moment I change Client to support Hybrid flow. I am not getting back claims given_name and family_name
I made below changes to my code.
Client configuration
public static IEnumerable<Client> Get()
{
return new[]
{
new Client
{
ClientId = "MVC",
ClientName = "MVC Client Name",
RedirectUris = new List<string>
{
"https://localhost:44302/"
},
Flow = Flows.Hybrid,//Changed this to Hybrid
AllowAccessToAllScopes = true
}
};
}
Server Configuration
app.UseOpenIdConnectAuthentication(new OpenIdConnectAuthenticationOptions
{
Authority = "https://localhost:44302/identity",
ClientId = "MVC",
RedirectUri = "https://localhost:44302/",
ResponseType = "code id_token token", //Changed response type
SignInAsAuthenticationType = "Cookies",
Scope = "openid profile"
});
After running applicaton I can see below claims returned by STS
Note that claims given_name and family_name are missing this time.
Have I missed anything?
Upvotes: 4
Views: 787
Reputation: 7435
When you only ask for an id_token all the claims for the user are in the id_token. When you change your request to get a token (either by asking for code or token) then only the user claims configured as "AlwaysInclude" are included in the id_token. The rest must be retrieved from the user info endpoint using the access_token you received. You can use the helper APIs in the IdentityModel library to easily access the user info endpoint. Our samples show how you can do this: https://github.com/IdentityServer/IdentityServer3.Samples/blob/master/source/Clients/MVC%20OWIN%20Client%20(Hybrid)/Startup.cs#L66
Upvotes: 4