2017-08-16 22 views
10

मैंने सोचा था कि जब मैंने एक दिन पहले एक नेट-निहित भालू लेखक वेबपी को .NET कोर 2.0 पर लागू करने के लिए सेट किया था, लेकिन मुझे अभी तक प्राप्त नहीं हुआ है कुछ भी दूरस्थ रूप से काम कर रहा है। यहाँ मैं क्या कर रहा हूँ की एक सूची है:एएसपी.NET कोर 2.0 बेयरर ऑथ पहचान के बिना

  • लागू एक वाहक टोकन एक ही परियोजना
  • उपयोग [अधिकृत] में संरक्षित WebAPI
  • जारी टोकन & ताज़ा टोकन कि समाप्ति बिंदु से नियंत्रित करने के लिए विशेषता एपीआई सतह के लिए उपयोग
  • नहीं ASP.Net पहचान (मैं बहुत हल्के वजन उपयोगकर्ता/सदस्यता reqs है)

मैं इमारत पहचान/दावे/लॉगिन में प्राचार्य और साथ पूरी तरह से ठीक हूँ का उपयोग संदर्भ को अनुरोध करने के लिए, लेकिन मैंने पहचान के बिना कोर 2.0 वेबपी में ऑथ/रीफ्रेश टोकन को जारी करने और उपभोग करने के तरीके पर एक उदाहरण नहीं देखा है। मैंने पहचान के बिना कुकीज़ के 1.x एमएसडीएन उदाहरण को देखा है, लेकिन इससे ऊपर की आवश्यकताओं को पूरा करने के लिए मुझे समझ में बहुत कुछ नहीं मिला।

मुझे लगता है कि यह एक आम परिदृश्य हो सकता है और यह मुश्किल नहीं होना चाहिए (शायद यह नहीं, शायद दस्तावेज़ीकरण/उदाहरणों की कमी हो सकती है?)। जहां तक ​​मैं कह सकता हूं, IdentityServer4 Core 2.0 Auth के साथ संगत नहीं है, opendiddict पहचान की आवश्यकता प्रतीत होती है। मैं टोकन एंडपॉइंट को एक अलग प्रक्रिया में होस्ट नहीं करना चाहता, लेकिन उसी वेबैपी उदाहरण के भीतर।

क्या कोई मुझे ठोस उदाहरण के लिए इंगित कर सकता है, या कम से कम कुछ मार्गदर्शन/विकल्प क्या हैं?

+0

मुझे भी इसका नमूना देखना अच्छा लगेगा। –

+0

पहचान जेडब्ल्यूटी तंत्र से तय की गई है। [यह] पढ़ें (https://docs.microsoft.com/en-us/aspnet/core/migration/1x-to-2x/identity-2x) और [यह] (https://pioneercode.com/post/ प्रमाणीकरण में एक-एएसपी-डॉट नेट कोर-api-भाग-3-json-वेब-टोकन)। आदाब अर्ज है। –

उत्तर

9

एएसपी.NET कोर 2.0 के साथ इसे संगत बनाने के लिए एक संपादन किया गया था।


सबसे पहले, कुछ Nuget संकुल:

  • Microsoft.AspNetCore.Authentication.JwtBearer
  • Microsoft.AspNetCore.Identity
  • System.IdentityModel.Tokens.Jwt
  • System.Security क्रिप्टोग्राफी.सीएसपी

था कुछ बुनियादी डेटा स्थानांतरण वस्तुओं में।

// Presumably you will have an equivalent user account class with a user name. 
public class User 
{ 
    public string UserName { get; set; } 
} 

public class JsonWebToken 
{ 
    public string access_token { get; set; } 

    public string token_type { get; set; } = "bearer"; 

    public int expires_in { get; set; } 

    public string refresh_token { get; set; } 
} 

को उचित रूप से में हो रही है, आप कि प्रवेश करें/टोकन वेब विधि की जरूरत है वास्तव में उपयोगकर्ता के लिए प्रमाणीकरण टोकन भेजना है।

[Route("api/token")] 
public class TokenController : Controller 
{ 
    private ITokenProvider _tokenProvider; 

    public TokenController(ITokenProvider tokenProvider) // We'll create this later, don't worry. 
    { 
     _tokenProvider = tokenProvider; 
    } 

    public JsonWebToken Get([FromQuery] string grant_type, [FromQuery] string username, [FromQuery] string password, [FromQuery] string refresh_token) 
    { 
     // Authenticate depending on the grant type. 
     User user = grant_type == "refresh_token" ? GetUserByToken(refresh_token) : GetUserByCredentials(username, password); 

     if (user == null) 
      throw new UnauthorizedAccessException("No!"); 

     int ageInMinutes = 20; // However long you want... 

     DateTime expiry = DateTime.UtcNow.AddMinutes(ageInMinutes); 

     var token = new JsonWebToken { 
      access_token = _tokenProvider.CreateToken(user, expiry), 
      expires_in = ageInMinutes * 60 
     }; 

     if (grant_type != "refresh_token") 
      token.refresh_token = GenerateRefreshToken(user); 

     return token; 
    } 

    private User GetUserByToken(string refreshToken) 
    { 
     // TODO: Check token against your database. 
     if (refreshToken == "test") 
      return new User { UserName = "test" }; 

     return null; 
    } 

    private User GetUserByCredentials(string username, string password) 
    { 
     // TODO: Check username/password against your database. 
     if (username == password) 
      return new User { UserName = username }; 

     return null; 
    } 

    private string GenerateRefreshToken(User user) 
    { 
     // TODO: Create and persist a refresh token. 
     return "test"; 
    } 
} 

आपने शायद देखा कि टोकन निर्माण अभी भी "जादू" कुछ काल्पनिक ITokenProvider द्वारा पारित किया गया है। टोकन प्रदाता इंटरफ़ेस को परिभाषित करें।

public interface ITokenProvider 
{ 
    string CreateToken(User user, DateTime expiry); 

    // TokenValidationParameters is from Microsoft.IdentityModel.Tokens 
    TokenValidationParameters GetValidationParameters(); 
} 

मैंने जेडब्ल्यूटी पर एक आरएसए सुरक्षा कुंजी के साथ टोकन निर्माण लागू किया। तो ...

public class RsaJwtTokenProvider : ITokenProvider 
{ 
    private RsaSecurityKey _key; 
    private string _algorithm; 
    private string _issuer; 
    private string _audience; 

    public RsaJwtTokenProvider(string issuer, string audience, string keyName) 
    { 
     var parameters = new CspParameters { KeyContainerName = keyName }; 
     var provider = new RSACryptoServiceProvider(2048, parameters); 

     _key = new RsaSecurityKey(provider); 

     _algorithm = SecurityAlgorithms.RsaSha256Signature; 
     _issuer = issuer; 
     _audience = audience; 
    } 

    public string CreateToken(User user, DateTime expiry) 
    { 
     JwtSecurityTokenHandler tokenHandler = new JwtSecurityTokenHandler(); 

     ClaimsIdentity identity = new ClaimsIdentity(new GenericIdentity(user.UserName, "jwt")); 

     // TODO: Add whatever claims the user may have... 

     SecurityToken token = tokenHandler.CreateJwtSecurityToken(new SecurityTokenDescriptor 
     { 
      Audience = _audience, 
      Issuer = _issuer, 
      SigningCredentials = new SigningCredentials(_key, _algorithm), 
      Expires = expiry.ToUniversalTime(), 
      Subject = identity 
     }); 

     return tokenHandler.WriteToken(token); 
    } 

    public TokenValidationParameters GetValidationParameters() 
    { 
     return new TokenValidationParameters 
     { 
      IssuerSigningKey = _key, 
      ValidAudience = _audience, 
      ValidIssuer = _issuer, 
      ValidateLifetime = true, 
      ClockSkew = TimeSpan.FromSeconds(0) // Identity and resource servers are the same. 
     }; 
    } 
} 

तो अब आप टोकन पैदा कर रहे हैं। वास्तव में उन्हें सत्यापित करने और इसे तार करने का समय। अपने स्टार्टअप सीएस पर जाएं।

ConfigureServices()

var tokenProvider = new RsaJwtTokenProvider("issuer", "audience", "mykeyname"); 
services.AddSingleton<ITokenProvider>(tokenProvider); 

services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme) 
    .AddJwtBearer(options => { 
     options.RequireHttpsMetadata = false; 
     options.TokenValidationParameters = tokenProvider.GetValidationParameters(); 
    }); 

// This is for the [Authorize] attributes. 
services.AddAuthorization(auth => { 
    auth.DefaultPolicy = new AuthorizationPolicyBuilder() 
     .AddAuthenticationSchemes(JwtBearerDefaults.AuthenticationScheme) 
     .RequireAuthenticatedUser() 
     .Build(); 
}); 

में फिर Configure()

public void Configure(IApplicationBuilder app) 
{ 
    app.UseAuthentication(); 

    // Whatever else you're putting in here... 

    app.UseMvc(); 
} 

होना चाहिए कि के बारे में आप सभी की जरूरत। उम्मीद है कि मैंने कुछ भी याद नहीं किया है।

खुश परिणाम है ...

[Authorize] // Yay! 
[Route("api/values")] 
public class ValuesController : Controller 
{ 
    // ... 
} 
+0

मैंने वास्तव में नए कोर 2 ऑथ स्टैक इत्यादि की सभी बातों के साथ खुद को रोल करने का भी सोचा नहीं था - मैंने सोचा कि यह बॉक्स से तैयार हो जाएगा। किसी भी मामले में, आपके समाधान से लापता एकमात्र चीज टोकन रीफ्रेश है, लेकिन यह ऊपर दिया गया छोटा है। एक प्रश्न - ये सुरक्षा टोकन अपारदर्शी या पारदर्शी हैं? (यानी टोकन के साथ प्रस्तुत करते समय, क्या ऑथ अचूक हो जाता है और पहचान को वेबपी संदर्भ में संलग्न करता है, या यह एक अतिरिक्त कदम है?) धन्यवाद मिच! – pseabury

+0

यह टोकन को अस्वीकार करता है और आपके लिए संदर्भ पहचान सेट करता है। आपके नियंत्रक में, 'User.Identity.Name' उपयोगकर्ता नाम होगा जो जेडब्ल्यूटी में पारित किया गया था। – Mitch

+0

और हाँ, मुझे अभी तक टोकन रीफ्रेश करने के लिए नहीं मिला है - हालांकि यह जेडब्ल्यूटी पीढ़ी कोड से काफी अलग है। कुछ यादृच्छिक हैश के माध्यम से टोकन जेनरेट करें, इसे स्टोर करें, और रीफ्रेश कॉल के दौरान इसे जांचें। यह कोड एक त्वरित एपीआई के लिए था जिसे मुझे .NET कोर बीटा चरण के दौरान वापस चाबुक करना पड़ा। अगर किसी के पास नई सुविधाओं पर सरल कार्यान्वयन है, तो यह बहुत अच्छा होगा। – Mitch

9

@Mitch जवाब पर बाद: प्रमाणीकरण ढेर काफ़ी नेट कोर 2.0 में जाने बदल दिया है। नीचे जवाब केवल नए कार्यान्वयन का उपयोग कर रहा है।

using System.Text; 
using Microsoft.AspNetCore.Authentication.JwtBearer; 
using Microsoft.AspNetCore.Builder; 
using Microsoft.AspNetCore.Hosting; 
using Microsoft.Extensions.Configuration; 
using Microsoft.Extensions.DependencyInjection; 
using Microsoft.IdentityModel.Tokens; 

namespace JwtWithoutIdentity 
{ 
    public class Startup 
    { 
     public Startup(IConfiguration configuration) 
     { 
      Configuration = configuration; 
     } 

     public IConfiguration Configuration { get; } 

     // This method gets called by the runtime. Use this method to add services to the container. 
     public void ConfigureServices(IServiceCollection services) 
     { 
      services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme) 
       .AddJwtBearer(cfg => 
       { 
        cfg.RequireHttpsMetadata = false; 
        cfg.SaveToken = true; 

        cfg.TokenValidationParameters = new TokenValidationParameters() 
        { 
         ValidIssuer = "me", 
         ValidAudience = "you", 
         IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes("rlyaKithdrYVl6Z80ODU350md")) //Secret 
        }; 

       }); 

      services.AddMvc(); 
     } 

     // This method gets called by the runtime. Use this method to configure the HTTP request pipeline. 
     public void Configure(IApplicationBuilder app, IHostingEnvironment env) 
     { 
      if (env.IsDevelopment()) 
      { 
       app.UseDeveloperExceptionPage(); 
      } 

      app.UseAuthentication(); 

      app.UseMvc(); 
     } 
    } 
} 

टोकन नियंत्रक

using System; 
using System.IdentityModel.Tokens.Jwt; 
using System.Security.Claims; 
using System.Text; 
using System.Threading.Tasks; 
using JwtWithoutIdentity.Models; 
using Microsoft.AspNetCore.Authorization; 
using Microsoft.AspNetCore.Mvc; 
using Microsoft.IdentityModel.Tokens; 

namespace JwtWithoutIdentity.Controllers 
{ 
    public class TokenController : Controller 
    { 

     [AllowAnonymous] 
     [Route("api/token")] 
     [HttpPost] 
     public async Task<IActionResult> Token(LoginViewModel model) 
     { 

      if (!ModelState.IsValid) return BadRequest("Token failed to generate"); 

      var user = (model.Password == "password" && model.Username == "username"); 

      if (!user) return Unauthorized(); 

      //Add Claims 
      var claims = new[] 
      { 
       new Claim(JwtRegisteredClaimNames.UniqueName, "data"), 
       new Claim(JwtRegisteredClaimNames.Sub, "data"), 
       new Claim(JwtRegisteredClaimNames.Jti, Guid.NewGuid().ToString()), 
      }; 

      var key = new SymmetricSecurityKey(Encoding.UTF8.GetBytes("rlyaKithdrYVl6Z80ODU350md")); //Secret 
      var creds = new SigningCredentials(key, SecurityAlgorithms.HmacSha256); 

      var token = new JwtSecurityToken("me", 
       "you", 
       claims, 
       expires: DateTime.Now.AddMinutes(30), 
       signingCredentials: creds); 

      return Ok(new JsonWebToken() 
      { 
       access_token = new JwtSecurityTokenHandler().WriteToken(token), 
       expires_in = 600000, 
       token_type = "bearer" 
      }); 
     } 
    } 
} 

मान नियंत्रक

using System.Collections.Generic; 
using Microsoft.AspNetCore.Authorization; 
using Microsoft.AspNetCore.Mvc; 

namespace JwtWithoutIdentity.Controllers 
{ 
    [Route("api/[controller]")] 
    public class ValuesController : Controller 
    { 
     // GET api/values 
     [Authorize] 
     [HttpGet] 
     public IEnumerable<string> Get() 
     { 
      var name = User.Identity.Name; 
      var claims = User.Claims; 

      return new string[] { "value1", "value2" }; 
     } 
    } 
} 

आशा इस मदद करता है!

+2

इसे पोस्ट करने के लिए धन्यवाद। ऐसा कुछ ढूंढ रहा था। मैं बस सोच रहा हूं कि यदि आप 'उपयोगकर्ता: पहचान' का उपयोग नहीं कर रहे हैं तो आपके पास अभी भी दावों और पहचान क्यों हैं। –

संबंधित मुद्दे