Код: Выделить всё
// Ensure OWIN startup is triggered
AppDomain.CurrentDomain.SetData("AppBaseDirectory", Server.MapPath("~/"));
// This will trigger the Configuration method in Startup.cs
Microsoft.Owin.Hosting.WebApp.Start("http://localhost:xxxxx");
< /code>
Вот мой startup.cs < /p>
using Microsoft.Owin;
using Microsoft.Owin.Security.Jwt;
using Owin;
using System;
using System.Text;
using Microsoft.Owin.Security;
using Microsoft.Owin.Security.OAuth;
[assembly: OwinStartup(typeof(namespace.Startup))]
namespace namespace
{
public class Startup
{
public void Configuration(IAppBuilder app)
{
ConfigureOAuth(app);
}
public void ConfigureOAuth(IAppBuilder app)
{
var issuer = "http://localhost:xxxxx";
var secret = Encoding.UTF8.GetBytes("TopSecret");
// OAuth Options for Token Generation and Validation
var options = new OAuthAuthorizationServerOptions
{
TokenEndpointPath = new PathString("/token"),
AccessTokenExpireTimeSpan = TimeSpan.FromMinutes(30),
AllowInsecureHttp = true,
Provider = new JWTAuthorizationServerProvider(),
RefreshTokenProvider = new RefreshTokenProvider()
};
app.UseOAuthAuthorizationServer(options);
app.UseJwtBearerAuthentication(new JwtBearerAuthenticationOptions
{
AuthenticationMode = AuthenticationMode.Active,
TokenValidationParameters = new Microsoft.IdentityModel.Tokens.TokenValidationParameters
{
ValidIssuer = issuer,
ValidateIssuer = true,
ValidAudience = issuer,
ValidateAudience = true,
IssuerSigningKey = new Microsoft.IdentityModel.Tokens.SymmetricSecurityKey(secret),
ValidateIssuerSigningKey = true,
ValidateLifetime = true,
ClockSkew = TimeSpan.Zero
}
});
}
}
}
< /code>
Вот мой jwtauthorizationserverprovider < /p>
using Microsoft.Owin.Security.OAuth;
using System.Security.Claims;
using System.Threading.Tasks;
using System;
using System.Text;
using System.IdentityModel.Tokens.Jwt;
using Microsoft.IdentityModel.Tokens;
using Microsoft.Owin.Security;
using namespace.Services;
public class JWTAuthorizationServerProvider : OAuthAuthorizationServerProvider
{
public override async Task GrantResourceOwnerCredentials(OAuthGrantResourceOwnerCredentialsContext context)
{
var username = context.UserName;
var password = context.Password;
var user = AuthenticateUser(username, password, "");
if (user == null)
{
context.SetError("invalid_grant", "The user name or password is incorrect.");
return;
}
var issuer = "http://localhost:xxxxx";
var audience = "http://localhost:xxxxx";
var secret = Encoding.UTF8.GetBytes("TopSecret");
var tokenHandler = new JwtSecurityTokenHandler();
var tokenDescriptor = new SecurityTokenDescriptor
{
Subject = new ClaimsIdentity(new Claim[]
{
new Claim(ClaimTypes.Name, username)
}),
Expires = DateTime.UtcNow.AddMinutes(30),
Issuer = issuer,
Audience = audience,
SigningCredentials = new SigningCredentials(new SymmetricSecurityKey(secret), SecurityAlgorithms.HmacSha256Signature)
};
var token = tokenHandler.CreateToken(tokenDescriptor);
var tokenString = tokenHandler.WriteToken(token);
context.Response.Headers.Add("Access-Control-Allow-Origin", new[] { "*" });
context.Response.Headers.Add("Access-Control-Allow-Methods", new[] { "GET", "POST" });
context.Response.Headers.Add("Access-Control-Allow-Headers", new[] { "Authorization", "Content-Type" });
context.Validated(new AuthenticationTicket(new ClaimsIdentity(context.Options.AuthenticationType), new AuthenticationProperties()));
context.Response.ContentType = "application/json";
context.Response.WriteAsync("{\"access_token\":\"" + tokenString + "\"}");
}
}
< /code>
Это мой обновлениеusing Microsoft.Owin.Security;
using Microsoft.Owin.Security.Infrastructure;
using System;
using System.Collections.Generic;
using System.Threading.Tasks;
public class RefreshTokenProvider : IAuthenticationTokenProvider
{
private static Dictionary refreshTokens = new Dictionary();
public async Task CreateAsync(AuthenticationTokenCreateContext context)
{
var refreshToken = Guid.NewGuid().ToString();
refreshTokens[refreshToken] = context.Ticket.Identity.Name;
context.SetToken(refreshToken);
}
public async Task ReceiveAsync(AuthenticationTokenReceiveContext context)
{
if (refreshTokens.TryGetValue(context.Token, out string username))
{
var identity = new System.Security.Claims.ClaimsIdentity("Bearer");
identity.AddClaim(new System.Security.Claims.Claim(System.Security.Claims.ClaimTypes.Name, username));
context.SetTicket(new AuthenticationTicket(identity, new AuthenticationProperties()));
}
else
{
context.Response.StatusCode = 400;
context.Response.ReasonPhrase = "Invalid refresh token";
}
}
public void Create(AuthenticationTokenCreateContext context) { CreateAsync(context).Wait(); }
public void Receive(AuthenticationTokenReceiveContext context) { ReceiveAsync(context).Wait(); }
}
< /code>
И, наконец, это мой jwttokenvalidator: < /p>
using System;
using System.IdentityModel.Tokens.Jwt;
using System.Security.Claims;
using System.Text;
using Microsoft.IdentityModel.Tokens;
public class JwtTokenValidator
{
private readonly string _secretKey = "TopSecret";
private readonly string _issuer = "http://localhost:xxxxx/"; /
private readonly string _audience = "http://localhost:xxxxx/";
public bool IsValidToken(string token)
{
try
{
var tokenHandler = new JwtSecurityTokenHandler();
var key = Encoding.UTF8.GetBytes(_secretKey);
var validationParameters = new TokenValidationParameters
{
ValidateIssuer = true,
ValidIssuer = _issuer,
ValidateAudience = true,
ValidAudience = _audience,
ValidateLifetime = true,
IssuerSigningKey = new SymmetricSecurityKey(key),
ValidateIssuerSigningKey = true,
ClockSkew = TimeSpan.Zero
};
var principal = tokenHandler.ValidateToken(token, validationParameters, out var validatedToken);
var claimsIdentity = principal.Identity as ClaimsIdentity;
var userIdClaim = claimsIdentity?.FindFirst(ClaimTypes.NameIdentifier);
Console.WriteLine($"Valid token for user: {userIdClaim?.Value}");
return true;
}
catch (SecurityTokenExpiredException)
{
Console.WriteLine("Token has expired.");
return false;
}
catch (SecurityTokenException)
{
Console.WriteLine("Invalid token.");
return false;
}
catch (Exception ex)
{
Console.WriteLine($"Token validation failed: {ex.Message}");
return false;
}
}
}
http: // localhost: xxxxx/token
Со следующим корпусом xwww-form-formod:
x-www /> Grant_type: "password" < /li>
username: "username" < /li>
Пароль: "Пароль" < /li>
< /ul>
Я знаю, что код слишком большая, но любая помощь очень ценится. < /p>
Подробнее здесь: https://stackoverflow.com/questions/795 ... lid-client