public void Security_SymmetricKeyTokenVerificationFact() { var issuer = "http://katanatesting.com/"; var sentIdentity = new ClaimsIdentity("CustomJwt", "MyNameClaimType", "MyRoleClaimType"); sentIdentity.AddClaims(new Claim[] { new Claim("MyNameClaimType", "TestUser"), new Claim("MyRoleClaimType", "Administrator") }); for (int i = 0; i < 5; i++) { sentIdentity.AddClaim(new Claim("ClaimId" + i.ToString(), i.ToString())); } var authProperties = new AuthenticationProperties(); var sentTicket = new AuthenticationTicket(sentIdentity, authProperties); var signingAlgorithm = new AesManaged(); var signingCredentials = new SigningCredentials(new SymmetricSecurityKey(signingAlgorithm.Key), SecurityAlgorithms.HmacSha256Signature, SecurityAlgorithms.Sha256Digest); var tokenValidationParameters = new TokenValidationParameters() { ValidAudience = issuer, SaveSigninToken = true, AuthenticationType = sentIdentity.AuthenticationType }; var formatter = new JwtFormat(tokenValidationParameters, new SymmetricKeyIssuerSecurityKeyProvider(issuer, signingAlgorithm.Key)); formatter.TokenHandler = new JwtSecurityTokenHandler(); var protectedtext = SecurityUtils.CreateJwtToken(sentTicket, issuer, signingCredentials); //Receive part var receivedTicket = formatter.Unprotect(protectedtext); var receivedClaims = receivedTicket.Identity.Claims; Assert.Equal("CustomJwt", receivedTicket.Identity.AuthenticationType); Assert.Equal(ClaimsIdentity.DefaultNameClaimType, receivedTicket.Identity.NameClaimType); Assert.Equal(ClaimsIdentity.DefaultRoleClaimType, receivedTicket.Identity.RoleClaimType); Assert.NotNull(receivedTicket.Identity.BootstrapContext); Assert.NotNull((receivedTicket.Identity.BootstrapContext) as string); Assert.Equal(issuer, receivedClaims.Where <Claim>(claim => claim.Type == "iss").FirstOrDefault().Value); Assert.Equal(issuer, receivedClaims.Where <Claim>(claim => claim.Type == "aud").FirstOrDefault().Value); Assert.NotEmpty(receivedClaims.Where <Claim>(claim => claim.Type == "exp").FirstOrDefault().Value); for (int i = 0; i < 5; i++) { sentIdentity.AddClaim(new Claim("ClaimId" + i.ToString(), i.ToString())); Assert.Equal(i.ToString(), receivedClaims.Where <Claim>(claim => claim.Type == "ClaimId" + i.ToString()).FirstOrDefault().Value); } Assert.Equal("TestUser", receivedClaims.Where <Claim>(claim => claim.Type == ClaimsIdentity.DefaultNameClaimType).FirstOrDefault().Value); Assert.Equal("Administrator", receivedClaims.Where <Claim>(claim => claim.Type == ClaimsIdentity.DefaultRoleClaimType).FirstOrDefault().Value); Assert.NotEmpty(receivedClaims.Where <Claim>(claim => claim.Type == "iat").FirstOrDefault().Value); Assert.NotEmpty(receivedClaims.Where <Claim>(claim => claim.Type == "jti").FirstOrDefault().Value); }
public void Security_X509CertificateTokenVerificationFact() { var issuer = "http://katanatesting.com/"; var sentIdentity = new ClaimsIdentity("CustomJwt", "MyNameClaimType", "MyRoleClaimType"); sentIdentity.AddClaims(new Claim[] { new Claim("MyNameClaimType", "TestUser"), new Claim("MyRoleClaimType", "Administrator") }); for (int i = 0; i < 5; i++) { sentIdentity.AddClaim(new Claim("ClaimId" + i.ToString(), i.ToString())); } var authProperties = new AuthenticationProperties(); var sentTicket = new AuthenticationTicket(sentIdentity, authProperties); var signingCertificate = GetACertificateWithPrivateKey(); var signingCredentials = new X509SigningCredentials(signingCertificate); var tokenValidationParameters = new TokenValidationParameters() { ValidAudience = issuer, SaveSigninToken = true, AuthenticationType = sentIdentity.AuthenticationType }; var formatter = new JwtFormat(tokenValidationParameters, new X509CertificateSecurityTokenProvider(issuer, signingCertificate)); formatter.TokenHandler = new JwtSecurityTokenHandler(); var protectedtext = SecurityUtils.CreateJwtToken(sentTicket, issuer, signingCredentials); //Receive part var receivedTicket = formatter.Unprotect(protectedtext); var receivedClaims = receivedTicket.Identity.Claims; Assert.Equal<string>("CustomJwt", receivedTicket.Identity.AuthenticationType); Assert.Equal<string>(ClaimsIdentity.DefaultNameClaimType, receivedTicket.Identity.NameClaimType); Assert.Equal<string>(ClaimsIdentity.DefaultRoleClaimType, receivedTicket.Identity.RoleClaimType); Assert.NotNull(receivedTicket.Identity.BootstrapContext); Assert.NotNull(((BootstrapContext)receivedTicket.Identity.BootstrapContext).Token); Assert.Equal<string>(issuer, receivedClaims.Where<Claim>(claim => claim.Type == "iss").FirstOrDefault().Value); Assert.Equal<string>(issuer, receivedClaims.Where<Claim>(claim => claim.Type == "aud").FirstOrDefault().Value); Assert.NotEmpty(receivedClaims.Where<Claim>(claim => claim.Type == "exp").FirstOrDefault().Value); for (int i = 0; i < 5; i++) { sentIdentity.AddClaim(new Claim("ClaimId" + i.ToString(), i.ToString())); Assert.Equal<string>(i.ToString(), receivedClaims.Where<Claim>(claim => claim.Type == "ClaimId" + i.ToString()).FirstOrDefault().Value); } Assert.Equal<string>("TestUser", receivedClaims.Where<Claim>(claim => claim.Type == ClaimsIdentity.DefaultNameClaimType).FirstOrDefault().Value); Assert.Equal<string>("Administrator", receivedClaims.Where<Claim>(claim => claim.Type == ClaimsIdentity.DefaultRoleClaimType).FirstOrDefault().Value); Assert.NotEmpty(receivedClaims.Where<Claim>(claim => claim.Type == "iat").FirstOrDefault().Value); Assert.NotEmpty(receivedClaims.Where<Claim>(claim => claim.Type == "jti").FirstOrDefault().Value); }
/// <summary> /// Validates the specified JWT and builds an AuthenticationTicket from it. /// </summary> /// <param name="protectedText">The JWT to validate.</param> /// <returns>An AuthenticationTicket built from the <paramref name="protectedText"/>.</returns> /// <exception cref="T:System.ArgumentNullException"> /// Thrown if the <paramref name="protectedText"/> is null or empty. /// </exception> /// <exception cref="T:System.ArgumentOutOfRangeException"> /// Thrown if the <paramref name="protectedText"/> is not a JWT. /// </exception> public AuthenticationTicket Unprotect(string protectedText) { if (string.IsNullOrWhiteSpace(protectedText)) { throw new ArgumentNullException(nameof(protectedText)); } var jwt = this.privateKey != null?JWT.Decode(protectedText, this.privateKey) : protectedText; var securityTokenProviders = this.settings.AllowedServers.Select( server => new Microsoft.Owin.Security.Jwt.SymmetricKeyIssuerSecurityTokenProvider( server.Issuer, TextEncodings.Base64Url.Decode(server.Secret))); var jwtFormat = new JwtFormat(this.settings.AllowedClients, securityTokenProviders); var ticket = jwtFormat.Unprotect(jwt); return(ticket); }
public async Task RequestToken_ValidateUsingExposedPublicKey_ValidationSucceded() { var mockServer = new MockIdentityServer(); var token = await mockServer.GetTokenForUser("blah"); var valParams = new TokenValidationParameters { IssuerSigningKeyResolver = (t, securityToken, keyIdentifier, validationParameters) => { var kid = keyIdentifier.OfType <NamedKeySecurityKeyIdentifierClause>() .Where(identifier => identifier.Name.Equals("kid")) .Select(identifier => identifier.Id) .Single(); return(validationParameters.IssuerSigningTokens.Single(key => key.Id == kid).SecurityKeys.First()); }, ValidAudience = "http://localhost/resources" }; var format = new JwtFormat(valParams, new Provider((await mockServer.GetPublicKeys()).Keys)); format.Unprotect(token); }
/// <summary> /// /// </summary> /// <param name="app"></param> public void Configuration(IAppBuilder app) { // 有关如何配置应用程序的详细信息,请访问 https://go.microsoft.com/fwlink/?LinkID=316888 var issuer = "http://localhost:51912/"; //发行者 var audience = "fNm0EDIXbfuuDowUpAoq5GTEiywV8eg0TpiIVnV8"; //观众 var secret = TextEncodings.Base64Url.Decode(OAuthCommon.Constants.Consts.JWT.Security.SecretKey); //秘钥 var signingKey = new System.IdentityModel.Tokens.InMemorySymmetricSecurityKey(secret); //令牌验证参数 TokenValidationParameters tokenValidationParameters = new TokenValidationParameters() { ValidateIssuerSigningKey = true, IssuerSigningKey = signingKey, // Validate the JWT Issuer (iss) claim ValidateIssuer = true, ValidIssuer = "http://localhost:51912/", // Validate the JWT Audience (aud) claim ValidateAudience = false, ValidAudience = audience, // Validate the token expiry ValidateLifetime = true, ClockSkew = TimeSpan.Zero }; //配置JwtBearer授权中间件 这个中间件的作用主要是解决由JWT方式提供的身份认证。算是Resource资源,认证服务器需要另外开发 app.UseJwtBearerAuthentication(new JwtBearerAuthenticationOptions() { TokenValidationParameters = tokenValidationParameters, AuthenticationMode = Microsoft.Owin.Security.AuthenticationMode.Active, AuthenticationType = "Bearer", AllowedAudiences = new[] { audience }, Description = new AuthenticationDescription(), Realm = "",//领域,范围; Provider = new OAuthBearerAuthenticationProvider() { //验证当前访客身份 OnValidateIdentity = context => { AuthenticationTicket ticket = context.Ticket; //校验身份是否过期 if (ticket.Properties.ExpiresUtc < DateTime.Now) { context.SetError("the token has expired!"); context.Rejected(); } else { context.Validated(ticket); } return(Task.FromResult <object>(context)); }, //处理授权令牌 OAuthBearerAuthenticationHandler //headers Authorization=Bear:token OnRequestToken = (context) => { context.Token = context.Token ?? context.Request.Query["access_token"]; if (context.Token != null) { context.Response.Headers["WWW-Authorization"] = "Bearer"; //protector IDataProtector protector = app.CreateDataProtector(typeof(OAuthAuthorizationServerMiddleware).Namespace, "Access_Token", "v1"); JwtFormat ticketDataFormat = new JwtFormat(tokenValidationParameters); var ticket = ticketDataFormat.Unprotect(context.Token);//从令牌字符串中,获取授权票据 context.Request.User = new ClaimsPrincipal(ticket.Identity); } return(Task.FromResult <object>(context)); }, OnApplyChallenge = (context) => { return(Task.FromResult <object>(context)); } }, IssuerSecurityTokenProviders = new IIssuerSecurityTokenProvider[] { new SymmetricKeyIssuerSecurityTokenProvider(issuer, secret) //对称加密 } }); }