#asp.net-mvc #asp.net-core #oauth-2.0 #identityserver4 #openid-connect
#asp.net-mvc #asp.net-core #oauth-2.0 #identityserver4 #OpenID-подключиться
Вопрос:
Я добавил своего Клиента в приложение IdentityServer4 identity provider.
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, т. е. электронной почты и роли?
Ответ №1:
Я прочитал несколько статей об этом. И это было решено. Мне пришлось добавить одну область.
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 добавлен токен в качестве типа ответа.
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();
}