ASP.NET কোর ওয়েব API প্রমাণীকরণ


98

আমি কীভাবে আমার ওয়েব পরিষেবায় প্রমাণীকরণ স্থাপন করব তা নিয়ে লড়াই করছি। পরিষেবাটি এএসপি.নেট কোর ওয়েব এপিআই দিয়ে তৈরি।

আমার সমস্ত ক্লায়েন্টদের (ডাব্লুপিএফ অ্যাপ্লিকেশন) ওয়েব পরিষেবা অপারেশনগুলিতে কল করতে একই শংসাপত্রগুলি ব্যবহার করা উচিত।

কিছু গবেষণা করার পরে, আমি বেসিক প্রমাণীকরণ নিয়ে এসেছি - এইচটিটিপি অনুরোধের শিরোনামে একটি ব্যবহারকারীর নাম এবং পাসওয়ার্ড প্রেরণ করছি। তবে কয়েক ঘন্টা গবেষণার পরে, আমার কাছে মনে হয় বেসিক প্রমাণীকরণ এএসপি.নেট কোরে যাওয়ার উপায় নয়।

আমি যে সংস্থানগুলি পেয়েছি তার বেশিরভাগই OAuth বা অন্য কোনও মিডলওয়্যার ব্যবহার করে প্রমাণীকরণ প্রয়োগ করে। তবে এটি আমার দৃশ্যধারণের পাশাপাশি এএসপি.নেট কোরের পরিচয় অংশটি ব্যবহার করার জন্য বড় আকারের বলে মনে হচ্ছে।

সুতরাং আমার লক্ষ্য অর্জনের সঠিক উপায়টি কী - এএসপি.নেট কোর ওয়েব পরিষেবাতে ব্যবহারকারীর নাম এবং পাসওয়ার্ড সহ সাধারণ প্রমাণীকরণ?

আগাম ধন্যবাদ!

উত্তর:


75

আপনি একটি মিডওয়্যার প্রয়োগ করতে পারেন যা বেসিক প্রমাণীকরণকে পরিচালনা করে।

public async Task Invoke(HttpContext context)
{
    var authHeader = context.Request.Headers.Get("Authorization");
    if (authHeader != null && authHeader.StartsWith("basic", StringComparison.OrdinalIgnoreCase))
    {
        var token = authHeader.Substring("Basic ".Length).Trim();
        System.Console.WriteLine(token);
        var credentialstring = Encoding.UTF8.GetString(Convert.FromBase64String(token));
        var credentials = credentialstring.Split(':');
        if(credentials[0] == "admin" && credentials[1] == "admin")
        {
            var claims = new[] { new Claim("name", credentials[0]), new Claim(ClaimTypes.Role, "Admin") };
            var identity = new ClaimsIdentity(claims, "Basic");
            context.User = new ClaimsPrincipal(identity);
        }
    }
    else
    {
        context.Response.StatusCode = 401;
        context.Response.Headers.Set("WWW-Authenticate", "Basic realm=\"dotnetthoughts.net\"");
    }
    await _next(context);
}

এই কোডটি এসপ নেট কোরের বিটা সংস্করণে লিখিত। আশা করি এটা সাহায্য করবে.


4
আপনার উত্তরের জন্য ধন্যবাদ! এটি ঠিক আমি যা খুঁজছিলাম - মৌলিক প্রমাণীকরণের জন্য একটি সহজ সমাধান।
ফেলিক্স

4
শংসাপত্রাদি ব্যবহারের কারণে এই কোডটিতে একটি বাগ আছে S ফেলিক্সের উত্তরের কোডটি এই সমস্যাটিতে ভুগছে না।
ফিল ডেনিস

111

এখন, আমাকে সঠিক দিক নির্দেশ করার পরে, এখানে আমার সম্পূর্ণ সমাধান:

এটি মিডলওয়্যার শ্রেণি যা প্রতিটি আগত অনুরোধে কার্যকর করা হয় এবং অনুরোধটির সঠিক শংসাপত্র রয়েছে কিনা তা যাচাই করে। যদি কোনও শংসাপত্র উপস্থিত না থাকে বা সেগুলি ভুল হয় তবে পরিষেবাটি 401 অননুমোদিত ত্রুটির সাথে সাথে প্রতিক্রিয়া জানায় ।

public class AuthenticationMiddleware
{
    private readonly RequestDelegate _next;

    public AuthenticationMiddleware(RequestDelegate next)
    {
        _next = next;
    }

    public async Task Invoke(HttpContext context)
    {
        string authHeader = context.Request.Headers["Authorization"];
        if (authHeader != null && authHeader.StartsWith("Basic"))
        {
            //Extract credentials
            string encodedUsernamePassword = authHeader.Substring("Basic ".Length).Trim();
            Encoding encoding = Encoding.GetEncoding("iso-8859-1");
            string usernamePassword = encoding.GetString(Convert.FromBase64String(encodedUsernamePassword));

            int seperatorIndex = usernamePassword.IndexOf(':');

            var username = usernamePassword.Substring(0, seperatorIndex);
            var password = usernamePassword.Substring(seperatorIndex + 1);

            if(username == "test" && password == "test" )
            {
                await _next.Invoke(context);
            }
            else
            {
                context.Response.StatusCode = 401; //Unauthorized
                return;
            }
        }
        else
        {
            // no authorization header
            context.Response.StatusCode = 401; //Unauthorized
            return;
        }
    }
}

মিডলওয়্যার এক্সটেনশানটি পরিষেবা স্টার্টআপ ক্লাসের কনফিগার পদ্ধতিতে কল করা দরকার

public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory)
{
    loggerFactory.AddConsole(Configuration.GetSection("Logging"));
    loggerFactory.AddDebug();

    app.UseMiddleware<AuthenticationMiddleware>();

    app.UseMvc();
}

এবং যে সব! :)

নেট কোর এবং প্রমাণীকরণের জন্য মিডলওয়্যারের জন্য খুব ভাল সংস্থান এখানে পাওয়া যাবে: https://www.exceptionnotfound.net/writing-custom-middleware-in-asp-net-core-1-0/


4
সম্পূর্ণ সমাধান পোস্ট করার জন্য ধন্যবাদ। তবে, আমাকে 'প্রসঙ্গটি যুক্ত করতে হয়েছিল had রেসপন্স.হেইডার্স .এড ("ডাব্লুডাব্লুডাব্লুডাব্লু-প্রমাণীকরণ", "বেসিক রিয়েলম = \" রিয়েলম \ "");' ব্রাউজারের শংসাপত্রগুলির অনুরোধ পাওয়ার জন্য 'কোনও অনুমোদন শিরোনাম' বিভাগে নেই।
m0n0ph0n

এই প্রমাণীকরণটি কতটা নিরাপদ? কেউ যদি অনুরোধ শিরোনামে স্নিগ্ধ করে ব্যবহারকারীর নাম / পাসওয়ার্ড পান?
বেওয়ার সালাহ

4
@ বেওয়ারসালাহ আপনাকে অবশ্যই https
ওয়াল

4
কিছু নিয়ন্ত্রকের বেনামে অনুমতি দেওয়া উচিত। এই মিডলওয়্যার সমাধানটি সেই ক্ষেত্রে ব্যর্থ হবে কারণ এটি প্রতিটি অনুরোধে অনুমোদনের শিরোনামের জন্য পরীক্ষা করবে।
কার্তিক

28

এটি কেবল নির্দিষ্ট নিয়ন্ত্রকদের জন্য ব্যবহার করতে উদাহরণস্বরূপ এটি ব্যবহার করুন:

app.UseWhen(x => (x.Request.Path.StartsWithSegments("/api", StringComparison.OrdinalIgnoreCase)), 
            builder =>
            {
                builder.UseMiddleware<AuthenticationMiddleware>();
            });

22

আমি মনে করি আপনি JWT (জসন ওয়েব টোকেন) এর সাথে যেতে পারেন।

প্রথমে আপনাকে প্যাকেজ সিস্টেম ইনস্টল করতে হবে dআডেন্টিটি মডেল.টোকেনস.জেডব্লিউটি:

$ dotnet add package System.IdentityModel.Tokens.Jwt

টোকেন জেনারেশন এবং এর মতো প্রমাণীকরণের জন্য আপনাকে একটি নিয়ামক যুক্ত করতে হবে:

public class TokenController : Controller
{
    [Route("/token")]

    [HttpPost]
    public IActionResult Create(string username, string password)
    {
        if (IsValidUserAndPasswordCombination(username, password))
            return new ObjectResult(GenerateToken(username));
        return BadRequest();
    }

    private bool IsValidUserAndPasswordCombination(string username, string password)
    {
        return !string.IsNullOrEmpty(username) && username == password;
    }

    private string GenerateToken(string username)
    {
        var claims = new Claim[]
        {
            new Claim(ClaimTypes.Name, username),
            new Claim(JwtRegisteredClaimNames.Nbf, new DateTimeOffset(DateTime.Now).ToUnixTimeSeconds().ToString()),
            new Claim(JwtRegisteredClaimNames.Exp, new DateTimeOffset(DateTime.Now.AddDays(1)).ToUnixTimeSeconds().ToString()),
        };

        var token = new JwtSecurityToken(
            new JwtHeader(new SigningCredentials(
                new SymmetricSecurityKey(Encoding.UTF8.GetBytes("Secret Key You Devise")),
                                         SecurityAlgorithms.HmacSha256)),
            new JwtPayload(claims));

        return new JwtSecurityTokenHandler().WriteToken(token);
    }
}

তারপরে আপডেটের পরে স্টার্টআপ.স ক্লাসটি নীচের মত দেখতে:

namespace WebAPISecurity
{   
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.AddMvc();

        services.AddAuthentication(options => {
            options.DefaultAuthenticateScheme = "JwtBearer";
            options.DefaultChallengeScheme = "JwtBearer";
        })
        .AddJwtBearer("JwtBearer", jwtBearerOptions =>
        {
            jwtBearerOptions.TokenValidationParameters = new TokenValidationParameters
            {
                ValidateIssuerSigningKey = true,
                IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes("Secret Key You Devise")),
                ValidateIssuer = false,
                //ValidIssuer = "The name of the issuer",
                ValidateAudience = false,
                //ValidAudience = "The name of the audience",
                ValidateLifetime = true, //validate the expiration and not before values in the token
                ClockSkew = TimeSpan.FromMinutes(5) //5 minute tolerance for the expiration date
            };
        });

    }

    // 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();
    }
}

এবং এটি হ'ল এখন যা অবশিষ্ট রয়েছে তা হ'ল [Authorize]আপনার পছন্দসই নিয়ন্ত্রণকারী বা ক্রিয়াকলাপগুলিতে বিশেষত্ব স্থাপন করা।

এখানে একটি সম্পূর্ণ সোজা ফরোয়ার্ড টিউটোরিয়াল একটি লিঙ্ক আছে।

http://www.blinkcare.com/2017/09/06/secure-web-api-in-asp-net-core/


9

আমি BasicAuthenticationHandlerবেসিক প্রমাণীকরণের জন্য প্রয়োগ করেছি যাতে আপনি এটি স্ট্যান্ডার্ড বৈশিষ্ট্য Authorizeএবং ব্যবহার করে ব্যবহার করতে পারেন AllowAnonymous

public class BasicAuthenticationHandler : AuthenticationHandler<BasicAuthenticationOptions>
{
    protected override Task<AuthenticateResult> HandleAuthenticateAsync()
    {
        var authHeader = (string)this.Request.Headers["Authorization"];

        if (!string.IsNullOrEmpty(authHeader) && authHeader.StartsWith("basic", StringComparison.OrdinalIgnoreCase))
        {
            //Extract credentials
            string encodedUsernamePassword = authHeader.Substring("Basic ".Length).Trim();
            Encoding encoding = Encoding.GetEncoding("iso-8859-1");
            string usernamePassword = encoding.GetString(Convert.FromBase64String(encodedUsernamePassword));

            int seperatorIndex = usernamePassword.IndexOf(':', StringComparison.OrdinalIgnoreCase);

            var username = usernamePassword.Substring(0, seperatorIndex);
            var password = usernamePassword.Substring(seperatorIndex + 1);

            //you also can use this.Context.Authentication here
            if (username == "test" && password == "test")
            {
                var user = new GenericPrincipal(new GenericIdentity("User"), null);
                var ticket = new AuthenticationTicket(user, new AuthenticationProperties(), Options.AuthenticationScheme);
                return Task.FromResult(AuthenticateResult.Success(ticket));
            }
            else
            {
                return Task.FromResult(AuthenticateResult.Fail("No valid user."));
            }
        }

        this.Response.Headers["WWW-Authenticate"]= "Basic realm=\"yourawesomesite.net\"";
        return Task.FromResult(AuthenticateResult.Fail("No credentials."));
    }
}

public class BasicAuthenticationMiddleware : AuthenticationMiddleware<BasicAuthenticationOptions>
{
    public BasicAuthenticationMiddleware(
       RequestDelegate next,
       IOptions<BasicAuthenticationOptions> options,
       ILoggerFactory loggerFactory,
       UrlEncoder encoder)
       : base(next, options, loggerFactory, encoder)
    {
    }

    protected override AuthenticationHandler<BasicAuthenticationOptions> CreateHandler()
    {
        return new BasicAuthenticationHandler();
    }
}

public class BasicAuthenticationOptions : AuthenticationOptions
{
    public BasicAuthenticationOptions()
    {
        AuthenticationScheme = "Basic";
        AutomaticAuthenticate = true;
    }
}

স্টার্টআপ.সি তে নিবন্ধন - app.UseMiddleware<BasicAuthenticationMiddleware>();। এই কোডের সাহায্যে আপনি স্ট্যান্ডার্ড অ্যাট্রিবিউট অটোরিজ সহ যে কোনও নিয়ামককে সীমাবদ্ধ করতে পারেন:

[Authorize(ActiveAuthenticationSchemes = "Basic")]
[Route("api/[controller]")]
public class ValuesController : Controller

এবং AllowAnonymousআপনি যদি অ্যাপ্লিকেশন স্তরে অনুমোদিত ফিল্টার প্রয়োগ করেন তবে অ্যাট্রিবিউট ব্যবহার করুন।


4
আমি আপনার কোডটি ব্যবহার করেছি, তবে আমি খেয়াল করেছি যে অনুমোদন (অ্যাক্টিভ অ্যাটেনটিকেশনশেমস = "বেসিক")] সেট করা আছে বা না প্রতিটি কলে মিডওয়্যারটি সক্রিয় হয়ে যায় যার ফলে প্রতিটি কন্ট্রোলার পছন্দসই না হয়েও বৈধ হয়ে যায়।
সিশার্পার

আমি এই উত্তরটি পছন্দ করি
KTOV

4
: এখানে উদাহরণ কাজ jasonwatmore.com/post/2018/09/08/...
bside

আমি মনে করি এটি উত্তর হ'ল উপায়, কারণ এটি আপনাকে সমাধানের ক্ষেত্রে আরও অনুমোদিত মান / অনুমোদনহীন গুণাবলী ব্যবহার করতে দেয়। তারপরে, প্রকল্পের পর্যায়ে পরে অন্য প্রমাণীকরণের স্কিমটি ব্যবহার করা সহজ হওয়া উচিত
ফ্রেডেরিক ঘিয়েলস

0

এই সর্বজনীন গিথুব রেপোতে https://github.com/boskjoett/BasicAuthWebApi আপনি বেসিক প্রমাণীকরণ দ্বারা সুরক্ষিত এন্ডপয়েন্ট সহ একটি এএসপি.নেট কোর 2.2 ওয়েব এপিআইয়ের একটি সাধারণ উদাহরণ দেখতে পাবেন।


আপনি যদি আপনার নিয়ামক (সিকিউরিভ্যালস কন্ট্রোলার) -এর প্রমাণীকরণযোগ্য পরিচয় ব্যবহার করতে চান, তবে টিকিট তৈরি করা অনুরোধ হিসাবে যথেষ্ট নয়। ব্যবহারকারী অবজেক্টটি খালি। প্রমাণীকরণহ্যান্ডলারের বর্তমান প্রসঙ্গে আমাদের এখনও কি এই দাবিগুলি প্রিন্সিপালকে অর্পণ করতে হবে? পুরানো ওয়েবএপিতে আমরা এভাবেই করেছি ...
pseabury

0

পূর্ববর্তী পোস্টগুলি যথাযথভাবে বলেছে, একটি উপায় হ'ল একটি কাস্টম বেসিক প্রমাণীকরণ মিডলওয়্যার বাস্তবায়ন করা। আমি এই ব্লগে ব্যাখ্যার সাথে সর্বোত্তম কার্যকারী কোডটি পেয়েছি: কাস্টম মিডলওয়্যার সহ বেসিক এথ

আমি একই ব্লগ উল্লেখ করেছি তবে 2 টি অভিযোজন করতে হয়েছিল:

  1. স্টার্টআপ ফাইলটিতে মিডলওয়্যার যুক্ত করার সময় -> ফাংশনটি কনফিগার করুন, অ্যাপ্লিকেশন যুক্ত করার আগে সর্বদা কাস্টম মিডলওয়্যার যুক্ত করুন UUseMvc ()।
  2. অ্যাপসেটেটিংস.জসন ফাইলের ব্যবহারকারীর নাম, পাসওয়ার্ড পড়ার সময়, স্টার্টআপ ফাইলটিতে স্ট্যাটিক পঠন সম্পত্তি যুক্ত করুন। তারপরে appsettings.json থেকে পড়ুন। শেষ পর্যন্ত, প্রকল্পের যে কোনও জায়গা থেকে মানগুলি পড়ুন। উদাহরণ:

    public class Startup
    {
      public Startup(IConfiguration configuration)
      {
        Configuration = configuration;
      }
    
      public IConfiguration Configuration { get; }
      public static string UserNameFromAppSettings { get; private set; }
      public static string PasswordFromAppSettings { get; private set; }
    
      //set username and password from appsettings.json
      UserNameFromAppSettings = Configuration.GetSection("BasicAuth").GetSection("UserName").Value;
      PasswordFromAppSettings = Configuration.GetSection("BasicAuth").GetSection("Password").Value;
    }
    

0

আপনি একটি ব্যবহার করতে পারেন ActionFilterAttribute

public class BasicAuthAttribute : ActionFilterAttribute
{
    public string BasicRealm { get; set; }
    protected NetworkCredential Nc { get; set; }

    public BasicAuthAttribute(string user,string pass)
    {
        this.Nc = new NetworkCredential(user,pass);
    }

    public override void OnActionExecuting(ActionExecutingContext filterContext)
    {
        var req = filterContext.HttpContext.Request;
        var auth = req.Headers["Authorization"].ToString();
        if (!String.IsNullOrEmpty(auth))
        {
            var cred = System.Text.Encoding.UTF8.GetString(Convert.FromBase64String(auth.Substring(6)))
                .Split(':');
            var user = new {Name = cred[0], Pass = cred[1]};
            if (user.Name == Nc.UserName && user.Pass == Nc.Password) return;
        }

        filterContext.HttpContext.Response.Headers.Add("WWW-Authenticate",
            String.Format("Basic realm=\"{0}\"", BasicRealm ?? "Ryadel"));
        filterContext.Result = new UnauthorizedResult();
    }
}

এবং আপনার নিয়ামকের সাথে বৈশিষ্ট্য যুক্ত করুন

[BasicAuth("USR", "MyPassword")]


-1

কৌণিক সহ এএসপি.নেট কোর 2.0

https://fullstackmark.com/post/13/jwt-authentication-with-aspnet-core-2-web-api-angular-5-net-core-identity-and-facebook-login

প্রমাণীকরণ ফিল্টার ধরণের ব্যবহার নিশ্চিত করুন

[অনুমোদন করুন (প্রমাণীকরণশিক্ষা = JwtBearerDephaults.AuthenticationScheme)]

আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.