现有 ASP.NET MVC 5 应用程序连接到 ASP.NET Core 6 Web 服务

问题描述 投票:0回答:1

我有一个使用 ASP.NET MVC 5 创建的稍微旧的 Web 应用程序。已使用 ASP.NET Core 6 Web API 创建了一个新的 Web 服务,并使用 JWT 进行保护,需要将其集成到此 Web 应用程序中。

这可能吗?如果是的话,有人可以引导我找到一些资源吗?我搜索了很多但找不到任何东西。谢谢。

asp.net-mvc-5 asp.net-core-webapi
1个回答
-1
投票

一个最小的例子:

API端:

令牌服务:

public interface ITokenService
    {
        string GenerateAccessToken(IEnumerable<Claim> claims);
        string GenerateRefreshToken();
        ClaimsPrincipal GetPrincipalFromExpiredToken(string token);
    }

    public class TokenService : ITokenService
    {
        public string GenerateAccessToken(IEnumerable<Claim> claims)
        {
            var secretKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes("yourkeyhere"));
            var signinCredentials = new SigningCredentials(secretKey, SecurityAlgorithms.HmacSha256);
            var tokeOptions = new JwtSecurityToken(
                issuer: "Issuer",
                audience: "Audience",
                claims: claims,
                expires: DateTime.Now.AddMinutes(20),
                signingCredentials: signinCredentials

            ); ;
            var tokenString = new JwtSecurityTokenHandler().WriteToken(tokeOptions);
            return tokenString;
        }
        public string GenerateRefreshToken()
        {
            var randomNumber = new byte[32];
            using (var rng = RandomNumberGenerator.Create())
            {
                rng.GetBytes(randomNumber);
                return Convert.ToBase64String(randomNumber);
            }
        }
        public ClaimsPrincipal GetPrincipalFromExpiredToken(string token)
        {
            var tokenValidationParameters = new TokenValidationParameters
            {
                ValidIssuer = "Issuer",
                ValidAudience = "Audience",
                ValidateAudience = true, 
                ValidateIssuer = true,
                ValidateIssuerSigningKey = true,
                IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes("yourkeyhere")),
                ValidateLifetime = false
            };
            var tokenHandler = new JwtSecurityTokenHandler();
            SecurityToken securityToken;
            var principal = tokenHandler.ValidateToken(token, tokenValidationParameters, out securityToken);
            var jwtSecurityToken = securityToken as JwtSecurityToken;
            if (jwtSecurityToken == null || !jwtSecurityToken.Header.Alg.Equals(SecurityAlgorithms.HmacSha256, StringComparison.InvariantCultureIgnoreCase))
                throw new SecurityTokenException("Invalid token");
            return principal;
        }
    }

程序.cs:

var builder = WebApplication.CreateBuilder(args);

// Add services to the container.
builder.Services.AddControllers().AddJsonOptions(op=>op.JsonSerializerOptions.PropertyNamingPolicy=null);

builder.Services.AddEndpointsApiExplorer();
builder.Services.AddSwaggerGen();
builder.Services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme).AddJwtBearer(o =>
{   
    o.TokenValidationParameters = new TokenValidationParameters
    {
        ValidIssuer = "Issuer",
        ValidAudience = "Audience",
        IssuerSigningKey = new SymmetricSecurityKey
        (Encoding.UTF8.GetBytes("yourkeyhere")),
        ValidateIssuer = true,
        ValidateAudience = true,
        ValidateLifetime = false,
        ValidateIssuerSigningKey = true
    };
});
//since you are fecthing token from another site,it's necessary to enable cors here
builder.Services.AddCors(op=>op.AddPolicy("MyPolicy",x=>x.AllowAnyOrigin()
.AllowAnyMethod().AllowAnyHeader()));
builder.Services.AddScoped<ITokenService, TokenService>();
var app = builder.Build();

// Configure the HTTP request pipeline.
if (app.Environment.IsDevelopment())
{
    app.UseSwagger();
    app.UseSwaggerUI();
}

app.UseHttpsRedirection();

app.UseAuthentication();
app.UseRouting();
app.UseCors("MyPolicy");
app.UseAuthorization();

app.MapControllers();

app.Run();

控制器:

[Route("api/[controller]")]
    [ApiController]
    public class LoginController : ControllerBase
    {

        private readonly ITokenService _tokenService;
        public LoginController(ITokenService tokenService)

        {
            _tokenService = tokenService;
        }
        [HttpPost]
        public IActionResult Login([FromBody] User user)
        {
            //check name/password here
            if (user.UserName is null)
                return Unauthorized();
            var claims = new List<Claim>
            {
               new Claim(ClaimTypes.Name, user.UserName),
            
             };

            var accessToken = _tokenService.GenerateAccessToken(claims);
            var refreshToken = _tokenService.GenerateRefreshToken();
            //you may store refresh token in db with userid/ip....
            return new JsonResult(new
            {
                AccessToken = accessToken,
                RefreshToken = refreshToken
            });
        }

        [HttpPost]
        [Route("refresh")]
        public IActionResult Refresh([FromBody] TokenModel tokenModel)
        {
           //if refresh token is valid,read claims from expired access token 
            string accessToken = tokenModel.AccessToken;
            string refreshToken = tokenModel.RefreshToken;
            var principal = _tokenService.GetPrincipalFromExpiredToken(accessToken);
            var username = principal.Identity.Name; 
            //you have to check if user is valid
            
            var newAccessToken = _tokenService.GenerateAccessToken(principal.Claims);
            var newRefreshToken = _tokenService.GenerateRefreshToken();
           
            return new JsonResult(new 
            {
                AccessToken = newAccessToken,
                RefreshToken = newRefreshToken
            });
        }
    }

    public class User
    {
        public string UserName { get; set; }

        public string PassWord { get; set; }
    }

    public class TokenModel
    {
        public string AccessToken { get; set; }

        public string RefreshToken { get; set; }
    }

在 asp.net MVC 项目中:

<button id="login">Login</button>
<button id="refresh">Refresh</button>
<button id="source"> Access Protected Resource</button>




<script src="~/Scripts/jquery-3.4.1.js"></script>
<script>
    $("#login").click(function () {
       
        $.ajax({
            url: 'https://localhost:7006/api/Login',
            type: 'POST',
            data: JSON.stringify({
                username: "name",
                password: "pwd"
            }),
            contentType: 'application/json; charset=utf-8',
            dataType: 'json',
           
            success: function (response) {
                console.log(response)                   
               
                localStorage.setItem("accesstoken", response.AccessToken)
                localStorage.setItem("refreshtoken", response.RefreshToken)
            }
        })
    })
    $("#refresh").click(function () {

        $.ajax({
            url: 'https://localhost:7006/api/Login/refresh',
            type: 'POST',
            data: JSON.stringify({
                AccessToken: localStorage.getItem("accesstoken"),
                RefreshToken: localStorage.getItem("refreshtoken")
            }),
            contentType: 'application/json; charset=utf-8',
            dataType: 'json',

            success: function (response) {
                console.log(response)
                

                localStorage.setItem("accesstoken", response.AccessToken)
                localStorage.setItem("refreshtoken", response.RefreshToken)
            }
        })
    })


    $("#source").click(function () {
        
        var auth = "Bearer " + localStorage.getItem("accesstoken")
        console.log(auth)
        $.ajax({
            url: 'https://localhost:7006/weatherforecast',
            type: 'GET',            
            headers: {
                "Authorization": auth
            },           
            success: function (resopnse) {
                var message=JSON.stringify(resopnse)
                alert(message);                
            }
        })
    }
    )
</script>

结果:

© www.soinside.com 2019 - 2024. All rights reserved.