在 ASP.NET MVC 5 客户端中获取声明,在 Identity Server 4 中为 TestUser 设置
Get claims in ASP.NET MVC 5 client, set for TestUser in Identity Server 4
我已将我的客户端添加到 IdentityServer4 身份提供商应用程序。
new Client
{
ClientId = "mvc4Simple",
ClientName = "MVC 4 Web Client",
AllowedGrantTypes = GrantTypes.HybridAndClientCredentials,
AllowAccessTokensViaBrowser = true,
RequireConsent = false,
ClientSecrets =
{
new Secret("secret".Sha256())
},
AlwaysIncludeUserClaimsInIdToken=true,
AlwaysSendClientClaims=true,
RedirectUris = { "https://localhost:44347/signin-oidc" },
PostLogoutRedirectUris = { "https://localhost:44347/signout-callback-oidc" },
AllowedScopes = new List<string>
{
IdentityServerConstants.StandardScopes.OpenId,
IdentityServerConstants.StandardScopes.Profile,
IdentityServerConstants.StandardScopes.Email
},
AllowOfflineAccess = true,
RequirePkce = false,
AllowPlainTextPkce = false
}
像这样的 IdentityResources
public static IEnumerable<IdentityResource> GetIdentityResources()
{
return new List<IdentityResource>
{
new IdentityResources.OpenId(),
new IdentityResources.Profile(),
new IdentityResources.Email()
};
}
我的 TestUser 也是这样
new TestUser
{
SubjectId = "12345678",
Username = "John",
Password = "12345",
Claims = new List<Claim> {
new Claim(ClaimTypes.Email, "xyz@gmail.com"),
new Claim(ClaimTypes.Role, "admin")
}
}
我的客户端是一个简单的 asp.net MVC 应用程序。客户端配置是这样的
[assembly: OwinStartup(typeof(MVCSimple.Startup))]
namespace MVCSimple
{
public partial class Startup
{
public void Configuration(IAppBuilder app)
{
JwtSecurityTokenHandler.DefaultInboundClaimTypeMap =
new Dictionary<string, string>();
app.UseCookieAuthentication(new CookieAuthenticationOptions
{
AuthenticationType = "cookie"
});
app.UseOpenIdConnectAuthentication(new OpenIdConnectAuthenticationOptions
{
AuthenticationType = "oidc",
Authority = "https://localhost:44316",
ClientId = "mvc4Simple",
ClientSecret = "secret",
ResponseType = "code id_token",
Scope = "openid profile",
UseTokenLifetime = false,
RedirectUri = "https://localhost:44347/signin-oidc",
PostLogoutRedirectUri = "https://localhost:44347/signout-callback-oidc",
SignInAsAuthenticationType = "cookie",
Notifications = new OpenIdConnectAuthenticationNotifications
{
SecurityTokenValidated = context =>
{
context.AuthenticationTicket.Identity.AddClaim(new
Claim(ClaimTypes.NameIdentifier, context.ProtocolMessage.IdToken));
return Task.FromResult(0);
},
RedirectToIdentityProvider = n =>
{
if (n.ProtocolMessage.RequestType ==
Microsoft.IdentityModel.Protocols.OpenIdConnect.OpenIdConnectRequestType.Logout)
{
var idTokenHint = n.OwinContext.Authentication.User.FindFirst("id_token");
if (idTokenHint != null)
{
n.ProtocolMessage.IdTokenHint = idTokenHint.Value;
}
}
return Task.FromResult(0);
}
}
});
}
}
}
身份验证工作正常。它会将我重定向回我的应用程序,但我想知道如何获得为我的 TestUser 设置的声明,即电子邮件和角色?
我读了一些关于它的文章。并得到解决。
我不得不添加一个范围。
new ApiScope("api1.read", "Read Access to API #1")
{
UserClaims={
ClaimTypes.Email,
ClaimTypes.Role
}
}
然后更改客户详细信息
new Client
{
ClientId = "mvc4Simple",
ClientName = "MVC 4 Web Client",
AllowedGrantTypes = GrantTypes.HybridAndClientCredentials,
AllowAccessTokensViaBrowser = true,
RequireConsent = false,
ClientSecrets =
{
new Secret("secret".Sha256())
},
AlwaysIncludeUserClaimsInIdToken=true,
AlwaysSendClientClaims=true,
RedirectUris = { "https://localhost:44347/signin-oidc" },
PostLogoutRedirectUris = { "https://localhost:44347/signout-callback-oidc" },
AllowedScopes = new List<string>
{
IdentityServerConstants.StandardScopes.OpenId,
IdentityServerConstants.StandardScopes.Profile,
IdentityServerConstants.StandardScopes.Email
"api1.read"
},
AllowOfflineAccess = true,
RequirePkce = false,
AllowPlainTextPkce = false
}
然后在 Startup class 添加 token 作为响应类型。
public void Configuration(IAppBuilder app)
{
JwtSecurityTokenHandler.DefaultInboundClaimTypeMap =
new Dictionary<string, string>();
app.UseCookieAuthentication(new CookieAuthenticationOptions
{
AuthenticationType = "cookie"
});
app.UseOpenIdConnectAuthentication(new OpenIdConnectAuthenticationOptions
{
AuthenticationType = "oidc",
Authority = "https://localhost:44316",
ClientId = "mvc4Simple",
ClientSecret = "secret",
ResponseType = "code id_token token",
Scope = "openid profile api1.read",//Include that scope here
UseTokenLifetime = false,
RedirectUri = "https://localhost:44347/signin-oidc",
PostLogoutRedirectUri = "https://localhost:44347/signout-callback-oidc",
SignInAsAuthenticationType = "cookie",
SaveTokens=true,
Notifications = new OpenIdConnectAuthenticationNotifications
{
SecurityTokenValidated = context =>
{
context.AuthenticationTicket.Identity.AddClaim(new
Claim(ClaimTypes.NameIdentifier,context.ProtocolMessage.IdToken));
context.AuthenticationTicket.Identity.AddClaim(new Claim("access_token",
context.ProtocolMessage.AccessToken));//Set access token in access_token claim
return Task.FromResult(0);
},
RedirectToIdentityProvider = n =>
{
if (n.ProtocolMessage.RequestType ==
Microsoft.IdentityModel.Protocols.OpenIdConnect.OpenIdConnectRequestType.Logout)
{
var idTokenHint =n.OwinContext.Authentication.User.FindFirst("id_token");
if (idTokenHint != null)
{
n.ProtocolMessage.IdTokenHint = idTokenHint.Value;
}
}
return Task.FromResult(0);
}
}
});
}
最后,我能够在我的控制器的操作方法中获得这些声明,如下所示
public ActionResult Index()
{
var identity = (ClaimsIdentity)User.Identity;
var token= identity.Claims.Where(x => x.Type == "access_token").ToList();
if (token.Count > 0)
{
var jwtToken = new JwtSecurityToken(token[0].Value);
var claimsjwt=jwtToken.Claims;//Here you can get all the claims set for the user i.e email , role
}
return View();
}
我已将我的客户端添加到 IdentityServer4 身份提供商应用程序。
new Client
{
ClientId = "mvc4Simple",
ClientName = "MVC 4 Web Client",
AllowedGrantTypes = GrantTypes.HybridAndClientCredentials,
AllowAccessTokensViaBrowser = true,
RequireConsent = false,
ClientSecrets =
{
new Secret("secret".Sha256())
},
AlwaysIncludeUserClaimsInIdToken=true,
AlwaysSendClientClaims=true,
RedirectUris = { "https://localhost:44347/signin-oidc" },
PostLogoutRedirectUris = { "https://localhost:44347/signout-callback-oidc" },
AllowedScopes = new List<string>
{
IdentityServerConstants.StandardScopes.OpenId,
IdentityServerConstants.StandardScopes.Profile,
IdentityServerConstants.StandardScopes.Email
},
AllowOfflineAccess = true,
RequirePkce = false,
AllowPlainTextPkce = false
}
像这样的 IdentityResources
public static IEnumerable<IdentityResource> GetIdentityResources()
{
return new List<IdentityResource>
{
new IdentityResources.OpenId(),
new IdentityResources.Profile(),
new IdentityResources.Email()
};
}
我的 TestUser 也是这样
new TestUser
{
SubjectId = "12345678",
Username = "John",
Password = "12345",
Claims = new List<Claim> {
new Claim(ClaimTypes.Email, "xyz@gmail.com"),
new Claim(ClaimTypes.Role, "admin")
}
}
我的客户端是一个简单的 asp.net MVC 应用程序。客户端配置是这样的
[assembly: OwinStartup(typeof(MVCSimple.Startup))]
namespace MVCSimple
{
public partial class Startup
{
public void Configuration(IAppBuilder app)
{
JwtSecurityTokenHandler.DefaultInboundClaimTypeMap =
new Dictionary<string, string>();
app.UseCookieAuthentication(new CookieAuthenticationOptions
{
AuthenticationType = "cookie"
});
app.UseOpenIdConnectAuthentication(new OpenIdConnectAuthenticationOptions
{
AuthenticationType = "oidc",
Authority = "https://localhost:44316",
ClientId = "mvc4Simple",
ClientSecret = "secret",
ResponseType = "code id_token",
Scope = "openid profile",
UseTokenLifetime = false,
RedirectUri = "https://localhost:44347/signin-oidc",
PostLogoutRedirectUri = "https://localhost:44347/signout-callback-oidc",
SignInAsAuthenticationType = "cookie",
Notifications = new OpenIdConnectAuthenticationNotifications
{
SecurityTokenValidated = context =>
{
context.AuthenticationTicket.Identity.AddClaim(new
Claim(ClaimTypes.NameIdentifier, context.ProtocolMessage.IdToken));
return Task.FromResult(0);
},
RedirectToIdentityProvider = n =>
{
if (n.ProtocolMessage.RequestType ==
Microsoft.IdentityModel.Protocols.OpenIdConnect.OpenIdConnectRequestType.Logout)
{
var idTokenHint = n.OwinContext.Authentication.User.FindFirst("id_token");
if (idTokenHint != null)
{
n.ProtocolMessage.IdTokenHint = idTokenHint.Value;
}
}
return Task.FromResult(0);
}
}
});
}
}
}
身份验证工作正常。它会将我重定向回我的应用程序,但我想知道如何获得为我的 TestUser 设置的声明,即电子邮件和角色?
我读了一些关于它的文章。并得到解决。 我不得不添加一个范围。
new ApiScope("api1.read", "Read Access to API #1")
{
UserClaims={
ClaimTypes.Email,
ClaimTypes.Role
}
}
然后更改客户详细信息
new Client
{
ClientId = "mvc4Simple",
ClientName = "MVC 4 Web Client",
AllowedGrantTypes = GrantTypes.HybridAndClientCredentials,
AllowAccessTokensViaBrowser = true,
RequireConsent = false,
ClientSecrets =
{
new Secret("secret".Sha256())
},
AlwaysIncludeUserClaimsInIdToken=true,
AlwaysSendClientClaims=true,
RedirectUris = { "https://localhost:44347/signin-oidc" },
PostLogoutRedirectUris = { "https://localhost:44347/signout-callback-oidc" },
AllowedScopes = new List<string>
{
IdentityServerConstants.StandardScopes.OpenId,
IdentityServerConstants.StandardScopes.Profile,
IdentityServerConstants.StandardScopes.Email
"api1.read"
},
AllowOfflineAccess = true,
RequirePkce = false,
AllowPlainTextPkce = false
}
然后在 Startup class 添加 token 作为响应类型。
public void Configuration(IAppBuilder app)
{
JwtSecurityTokenHandler.DefaultInboundClaimTypeMap =
new Dictionary<string, string>();
app.UseCookieAuthentication(new CookieAuthenticationOptions
{
AuthenticationType = "cookie"
});
app.UseOpenIdConnectAuthentication(new OpenIdConnectAuthenticationOptions
{
AuthenticationType = "oidc",
Authority = "https://localhost:44316",
ClientId = "mvc4Simple",
ClientSecret = "secret",
ResponseType = "code id_token token",
Scope = "openid profile api1.read",//Include that scope here
UseTokenLifetime = false,
RedirectUri = "https://localhost:44347/signin-oidc",
PostLogoutRedirectUri = "https://localhost:44347/signout-callback-oidc",
SignInAsAuthenticationType = "cookie",
SaveTokens=true,
Notifications = new OpenIdConnectAuthenticationNotifications
{
SecurityTokenValidated = context =>
{
context.AuthenticationTicket.Identity.AddClaim(new
Claim(ClaimTypes.NameIdentifier,context.ProtocolMessage.IdToken));
context.AuthenticationTicket.Identity.AddClaim(new Claim("access_token",
context.ProtocolMessage.AccessToken));//Set access token in access_token claim
return Task.FromResult(0);
},
RedirectToIdentityProvider = n =>
{
if (n.ProtocolMessage.RequestType ==
Microsoft.IdentityModel.Protocols.OpenIdConnect.OpenIdConnectRequestType.Logout)
{
var idTokenHint =n.OwinContext.Authentication.User.FindFirst("id_token");
if (idTokenHint != null)
{
n.ProtocolMessage.IdTokenHint = idTokenHint.Value;
}
}
return Task.FromResult(0);
}
}
});
}
最后,我能够在我的控制器的操作方法中获得这些声明,如下所示
public ActionResult Index()
{
var identity = (ClaimsIdentity)User.Identity;
var token= identity.Claims.Where(x => x.Type == "access_token").ToList();
if (token.Count > 0)
{
var jwtToken = new JwtSecurityToken(token[0].Value);
var claimsjwt=jwtToken.Claims;//Here you can get all the claims set for the user i.e email , role
}
return View();
}