401 এর চেয়ে অননুমোদিত ওয়েবপি কল লগইন পৃষ্ঠায় ফিরছে


179

আমি কীভাবে আমার এমভিসি / ওয়েবপিপি প্রকল্পটি কনফিগার করব যাতে একটি রেজার ভিউ থেকে ডাকা একটি ওয়েবপি পদ্ধতি যখন অননুমোদিত থাকে তখন লগইনপৃষ্ঠায় ফিরে আসে না?

এটি একটি এমভিসি 5 অ্যাপ্লিকেশন যার সাথে জাভাস্ক্রিপ্টের মাধ্যমে কল করার জন্য ওয়েবএপিআই কন্ট্রোলার রয়েছে।

নীচে দুটি পদ্ধতি

[Route("api/home/LatestProblems")]      
[HttpGet()]
public List<vmLatestProblems> LatestProblems()
{
    // Something here
}

[Route("api/home/myLatestProblems")]
[HttpGet()]
[Authorize(Roles = "Member")]
public List<vmLatestProblems> mylatestproblems()
{
   // Something there
}

নিম্নলিখিত কৌণিক কোডের মাধ্যমে কল করা হয়:

angular.module('appWorship').controller('latest', 
    ['$scope', '$http', function ($scope,$http) {         
        var urlBase = baseurl + '/api/home/LatestProblems';
        $http.get(urlBase).success(function (data) {
            $scope.data = data;
        }).error(function (data) {
            console.log(data);
        });
        $http.get(baseurl + '/api/home/mylatestproblems')
          .success(function (data) {
            $scope.data2 = data;
        }).error(function (data) {
            console.log(data);
        });  
    }]
);

সুতরাং আমি লগ ইন করছি না এবং প্রথম পদ্ধতিটি সাফল্যের সাথে ডেটা ফেরত দেয়। দ্বিতীয় পদ্ধতিটি (সাফল্যের ফাংশনে) ডেটা দেয় যা লগইন পৃষ্ঠার সমতুল্য থাকে। উদাহরণস্বরূপ, আপনি যদি এমভিসি-তে পাবেন তবে আপনি যদি কোনও কন্ট্রোলার অ্যাকশন অনুরোধ করেন যা [অনুমোদন] এর সাথে স্ট্যাম্পযুক্ত ছিল এবং আপনি লগ ইন না হয়ে থাকেন।

আমি এটি 401 অননুমোদিত ফিরিয়ে আনতে চাই, যাতে ব্যবহারকারীরা লগ ইন করেছেন কি না তার ভিত্তিতে আমি বিভিন্ন ডেটা প্রদর্শন করতে পারি। আদর্শভাবে যদি ব্যবহারকারী লগ ইন থাকে আমি কন্ট্রোলারের ব্যবহারকারীর সম্পত্তি অ্যাক্সেস করতে সক্ষম হতে চাই যাতে আমি সেই সদস্যের সাথে সম্পর্কিত ডেটা ফিরিয়ে দিতে পারি।

আপডেট: যেহেতু প্রস্তাবনার কেউ নিচে আর কাজ হবে বলে মনে হচ্ছে (পরিচয় বা WebAPI পরিবর্তন) উপর একটি কাঁচা উদাহরণ সৃষ্টি Ive GitHub যা সমস্যা চিত্রিত করা উচিত নয়।

উত্তর:


78

দুটি অথরিজঅ্যাট্রিবিউট বাস্তবায়ন রয়েছে এবং আপনাকে এটি নিশ্চিত করতে হবে যে আপনি ওয়েব এপিআই এর জন্য সঠিকটি উল্লেখ করছেন। এখানে সিস্টেম.ওয়েব.এইচটিপি.অর্টিভাইজ অ্যাট্রিবিউট রয়েছে যা ওয়েব এপিআই এর জন্য এবং সিস্টেম.ওয়েব.এমভিসি.অর্টিভাইজ অ্যাট্রিবিউট যা দর্শন সহ নিয়ন্ত্রণকারীদের জন্য ব্যবহৃত হয়। HTTP.AuthorizeAttribute 401 ত্রুটি ফিরিয়ে দেবে যদি অনুমোদন ব্যর্থ হয় এবং Mvc.AuthorizeAttribute লগইন পৃষ্ঠায় পুনর্নির্দেশ করবে।

11/26/2013 আপডেট হয়েছে

তাই মনে হচ্ছে যে ব্রক অ্যালেন নির্দিষ্ট কিছু আয়তন বহুলাংশে MVC 5 পরিবর্তিত হয়েছে তার প্রবন্ধে । আমার ধারণা OWIN পাইপলাইনটি গ্রহণ করে এবং কিছু নতুন আচরণের পরিচয় দেয়। এখন যখন ব্যবহারকারী অনুমোদিত নয় তখন এইচটিটিপি শিরোনামে 200 এর একটি স্থিতি নিম্নলিখিত তথ্য সহ ফিরে আসে।

X-Responded-JSON: {"status":401,"headers":{"location":"http:\/\/localhost:59540\/Account\/Login?ReturnUrl=%2Fapi%2FTestBasic"}}

ত্রুটি শাখায় 401 স্থিতি অনুসন্ধানের পরিবর্তে আপনি কীভাবে এটি পরিচালনা করবেন তা নির্ধারণ করতে শিরোনামে এই তথ্যটি পরীক্ষা করতে ক্লায়েন্টের পক্ষে আপনার যুক্তি পরিবর্তন করতে পারে।

আমি একটি কাস্টম মধ্যে এই আচরণ ওভাররাইড করার চেষ্টা AuthorizeAttribute প্রতিক্রিয়া স্থিতি সেট করে OnAuthorization এবং HandleUnauthorizedRequest পদ্ধতি।

actionContext.Response = new HttpResponseMessage(System.Net.HttpStatusCode.Unauthorized);

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

আমি ব্রোক অ্যালেনের সমাধানটি পরীক্ষা করেছিলাম এবং যখন আমি কোন জিকুয়ারি এজ্যাক্স কলটি ব্যবহার করতাম তখন এটি কার্যকর হয়েছিল। যদি এটি আপনার পক্ষে কাজ করে না তবে আমার অনুমানটি এটি কারণ আপনি কৌনিক ব্যবহার করছেন। ফিডলারের সাহায্যে আপনার পরীক্ষা চালান এবং নীচেরটি আপনার শিরোনামে রয়েছে কিনা তা দেখুন।

X-Requested-With: XMLHttpRequest

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


আমি মনে করি আমি System.web.http.authorizeattribute ব্যবহার করছি, কমপক্ষে এই ওয়েবপিকন্ট্রোলারের কাছে system.web.mvc ব্যবহার করা নেই এবং অনুমোদিত বৈশিষ্ট্যের সংজ্ঞাতে গিয়ে আমাকে system.web.http
টিম

হাই @ কেভিন-জাংহানস এখানে পুরোপুরি বিভ্রান্ত। শিবার উপরের উদাহরণটিতে একটি এমভিসি অনুমোদনের বৈশিষ্ট্য ব্যবহার করা হয়েছে যা অবশ্যই আমি একটি ওয়েবাপি অ্যাকশনে প্রয়োগ করতে পারি না, ব্রোক অ্যালেনের উদাহরণটি কাজ করতে দেখা যায় না তবে মনে হয় না যে এটি অজ্যাক্স অনুরোধটি আমি যখন পদক্ষেপ নেব তখন।
টিম

1
কেবলমাত্র এই উত্তরটি চিহ্নিত করেছেন (মনে করুন স্ট্যাকওভারফ্লো বিজ্ঞপ্তি প্রেরণ করছে না) সমস্যাটি বর্ণনা করার জন্য আমি একটি গিথুব উদাহরণ যোগ করেছি এবং এখন আপনার কৌণিক শিরোনামগুলিতে সংশোধন করেছি। ধন্যবাদ। তবে এটি ঠিক মনে হয় না যে আমি অনুমোদনযোগ্য বৈশিষ্ট্যে এমন কোনও সম্পত্তি নেই যা আমি যাচাই করতে পারি বা আপনি উল্লিখিত মূল কার্যকারিতা আর কাজ করে না।
টিম

3
পোস্টম্যান এবং শিরোলেখের পরম এক্স-রিকুয়েস্টড-সহ: এক্সএমএলএইচটিপিআরকোয়েস্ট আমার পক্ষে কাজ করে ... ধন্যবাদ
চেমিট্যাক্সিস

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

122

ব্রুক অ্যালেনের কুকি প্রমাণীকরণ এবং OWIN ব্যবহার করার সময় এজ্যাক্স কলগুলির জন্য কীভাবে 401 ফিরবেন সে সম্পর্কে একটি দুর্দান্ত ব্লগ পোস্ট রয়েছে। http://brockallen.com/2013/10/27/using-cookie-authentication-middleware-with-web-api-and-401-response-codes/

এটি স্টার্টআপ.আথ.সি.সি. ফাইলগুলিতে কনফিগারআউথ পদ্ধতিতে রাখুন:

app.UseCookieAuthentication(new CookieAuthenticationOptions
{
  AuthenticationType = DefaultAuthenticationTypes.ApplicationCookie,
  LoginPath = new PathString("/Account/Login"),
  Provider = new CookieAuthenticationProvider
  {
    OnApplyRedirect = ctx =>
    {
      if (!IsAjaxRequest(ctx.Request))
      {
        ctx.Response.Redirect(ctx.RedirectUri);
      }
    }
  }
});

private static bool IsAjaxRequest(IOwinRequest request)
{
  IReadableStringCollection query = request.Query;
  if ((query != null) && (query["X-Requested-With"] == "XMLHttpRequest"))
  {
     return true;
  }
  IHeaderDictionary headers = request.Headers;
  return ((headers != null) && (headers["X-Requested-With"] == "XMLHttpRequest"));
}

68
এর মধ্যে একটি পার্থক্য: আপনার সমস্ত ওয়েব এপিআই কল যদি কোনও নির্দিষ্ট পথে চলে যায়, যেমন /api, আপনি পুনঃনির্দেশ করবেন কিনা তা নির্ধারণের জন্য আপনি এই পথটি ব্যবহার করতে পারেন। এটি বিশেষত কার্যকর যদি আপনার ক্লায়েন্ট থাকে যা JSON এর মতো অন্যান্য ফর্ম্যাট ব্যবহার করে। IsAjaxRequestসাথে কলটি প্রতিস্থাপন করুন if (!context.Request.Path.StartsWithSegments(new PathString("/api")))
এডওয়ার্ড ব্রে

পার্টিতে দেরীতে, তবে এই পদ্ধতিটিই কেবল আমার জন্য উদ্ভূত এবং এটি আরও "নির্ভুল" বলে মনে হয়।
স্টিফেন কলিন্স

এমনকি পার্টিতে দেরী (র) হয়েছে, তবে এটি খুব কার্যকর প্রমাণিত হয়েছে ... এটি আমার মনের ভাব বোধ করে যে ডিফল্ট উত্সাহিত কোডটি এতটাই হতাশাজনকভাবে ডিবাগ করার জন্য কঠিন আচরণ করে।
নিক

আপনি যদি কোনও ওয়েবএপি সমাধানের পরে থাকেন তবে মানিকের উত্তরটি এখানে উচ্চ ভোট প্রাপ্ত মন্তব্যের একটি ভাল বিকল্প alternative
ডানচ

5
সি # 6 ব্যবহার করে, এখানে ইসএক্স্যাক্সের একটি ছোট সংস্করণ রয়েছে: private static bool IsAjaxRequest(IOwinRequest request) { return request.Query?["X-Requested-With"] == "XMLHttpRequest" || request.Headers?["X-Requested-With"] == "XMLHttpRequest"; }
পিটার আর্নহোম

85

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

আপনি যদি এখানে আসপ নেট পরিচয় এবং ওউন ভিত্তিক প্রমাণীকরণ ব্যবহার করেন তবে এই সমস্যাটি সমাধান করতে সহায়তা করতে পারে এমন একটি কোড:

public void ConfigureAuth(IAppBuilder app)
{
    app.UseCookieAuthentication(new CookieAuthenticationOptions
    {
        AuthenticationType = DefaultAuthenticationTypes.ApplicationCookie,
        LoginPath = new PathString("/Account/Login"),
        Provider = new CookieAuthenticationProvider()
        {
            OnApplyRedirect = ctx =>
            {
                if (!IsApiRequest(ctx.Request))
                {
                    ctx.Response.Redirect(ctx.RedirectUri);
                }
            }
        }
    });

    app.UseExternalSignInCookie(DefaultAuthenticationTypes.ExternalCookie);
}


private static bool IsApiRequest(IOwinRequest request)
{
    string apiPath = VirtualPathUtility.ToAbsolute("~/api/");
    return request.Uri.LocalPath.StartsWith(apiPath);
}

1
আমি অনুরোধগুলি পাঠ্য / এইচটিএমএল বা অ্যাপ্লিকেশন / এক্সএইচটিএমএলকে প্রতিক্রিয়া হিসাবে গ্রহণ করে কিনা তা যাচাই করার জন্য আমি বৈষম্যমূলক পরিবর্তন করেছি, তারা যদি আমি ধরে না নিই যে এটি "স্বয়ংক্রিয়" ক্লায়েন্টের অনুরোধ, যেমন একটি
এজাক্স

4
আমিও এই পদ্ধতির পছন্দ করি। আমি কেবল যুক্ত করেছিলাম লোকালপথে রূপান্তর করা o টলএলওয়ার () তারা "/ এপিআই" বা অন্য কোনও কিছুর জন্য অনুরোধ করে।
ফার্স্ট বিভাগ

1
অনেক ধন্যবাদ. এটা আমার দিন বাঁচায়। :)
অমিত কুমার

কারও সাথে কি ভাগ্য হচ্ছে? কুকিঅথেন্টিফিকেশনঅ্যাপশনগুলির আর অ্যা্যাসনেট কোর 1.1 হিসাবে সরবরাহকারীর সম্পত্তি নেই।
জেরেমি

27

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

আমি অন্য পদ্ধতির Suppress-Redirectবিকল্পটি বেছে নিয়েছি নতুন শিরোনামের প্রতিক্রিয়া ইনজেকশন করা: যদি ওয়েবএপি থেকে প্রতিক্রিয়াগুলি আসে। বাস্তবায়ন হ্যান্ডলারের উপর রয়েছে:

public class SuppressRedirectHandler : DelegatingHandler
{
    /// <summary>
    protected override Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
    {
        return base.SendAsync(request, cancellationToken).ContinueWith(task =>
        {
            var response = task.Result;
            response.Headers.Add("Suppress-Redirect", "True");
            return response;
        }, cancellationToken);
    }
}

এবং এই হ্যান্ডলারটিকে বিশ্ব স্তরের ওয়েবএপিতে নিবন্ধ করুন:

config.MessageHandlers.Add(new SuppressRedirectHandler());

সুতরাং, ওউইনআরআউটআপ আপনি প্রতিক্রিয়া শিরোনাম আছে কিনা তা পরীক্ষা করতে সক্ষম Suppress-Redirect:

public void Configuration(IAppBuilder app)
{
    app.UseCookieAuthentication(new CookieAuthenticationOptions
    {
        AuthenticationMode = AuthenticationMode.Active,
        AuthenticationType = DefaultApplicationTypes.ApplicationCookie,
        ExpireTimeSpan = TimeSpan.FromMinutes(48),

        LoginPath = new PathString("/NewAccount/LogOn"),

        Provider = new CookieAuthenticationProvider()
        {
            OnApplyRedirect = ctx =>
            {
                var response = ctx.Response;
                if (!IsApiResponse(ctx.Response))
                {
                    response.Redirect(ctx.RedirectUri);
                }
            }
        }
    });
}

private static bool IsApiResponse(IOwinResponse response)
{
    var responseHeader = response.Headers;

    if (responseHeader == null) 
        return false;

    if (!responseHeader.ContainsKey("Suppress-Redirect"))
        return false;

    if (!bool.TryParse(responseHeader["Suppress-Redirect"], out bool suppressRedirect))
        return false;

    return suppressRedirect;
}

ধন্যবাদ ! আমাদের API গুলি জামারিন / অ্যান্ড্রয়েড ব্যতীত প্রতিটি প্ল্যাটফর্মে কাজ করেছিল। এই সমাধানটি ব্যবহার করবে
জুরিয়ন

17

পূর্ববর্তী সংস্করণগুলিতে এএসপি.এনইটি-তে আপনাকে এই কাজটি করার জন্য পুরো গুচ্ছটি করতে হয়েছিল ।

সুসংবাদটি হ'ল, যেহেতু আপনি এএসপি.নেট 4.5 ব্যবহার করছেন। আপনি নতুন এইচটিটিপিআরস্পোনস ব্যবহার করে ফর্ম প্রমাণীকরণ পুনর্নির্দেশ অক্ষম করতে পারেন uসপ্রেসফোর্সসঅথেন্টিফিকেশন রিডাইরেক্ট সম্পত্তি।

ইন Global.asax:

protected void Application_EndRequest(Object sender, EventArgs e)
{
        HttpApplication context = (HttpApplication)sender;
        context.Response.SuppressFormsAuthenticationRedirect = true;
}

সম্পাদনা : আপনি সের্গে জায়েজদিনের এই নিবন্ধটিও একবার দেখে নিতে চাইতে পারেন যা আপনি যা করতে চেষ্টা করছেন তা সম্পাদন করার আরও বিশুদ্ধ উপায় রয়েছে has

প্রাসঙ্গিক কোড স্নিপেট এবং লেখকের বিবরণ নীচে আটকানো হয়েছে। কোড এবং বর্ণনার মূল লেখক - সের্গে জেউজদিন

প্রথম - আসুন বর্তমান HTTP- অনুরোধটি AJAX- অনুরোধ কিনা তা নির্ধারণ করুন। যদি হ্যাঁ, আমাদের এইচটিটিপি 401 এর পরিবর্তে এইচটিটিপি 302 প্রতিস্থাপন করা উচিত:

public class ApplicationAuthorizeAttribute : AuthorizeAttribute
{
    protected override void HandleUnauthorizedRequest(AuthorizationContext filterContext)
    {
        var httpContext = filterContext.HttpContext;
        var request = httpContext.Request;
        var response = httpContext.Response;

        if (request.IsAjaxRequest())
            response.SuppressFormsAuthenticationRedirect = true;

        base.HandleUnauthorizedRequest(filterContext);
    }
}

দ্বিতীয় - আসুন একটি শর্ত যুক্ত করুন: যদি ব্যবহারকারী প্রমাণীকৃত হয় তবে আমরা HTTP 403 প্রেরণ করব; এবং অন্যথায় HTTP 401।

public class ApplicationAuthorizeAttribute : AuthorizeAttribute
{
    protected override void HandleUnauthorizedRequest(AuthorizationContext filterContext)
    {
        var httpContext = filterContext.HttpContext;
        var request = httpContext.Request;
        var response = httpContext.Response;
        var user = httpContext.User;

        if (request.IsAjaxRequest())
        {
            if (user.Identity.IsAuthenticated == false)
                response.StatusCode = (int)HttpStatusCode.Unauthorized;
            else
                response.StatusCode = (int)HttpStatusCode.Forbidden;

            response.SuppressFormsAuthenticationRedirect = true;
            response.End();
        }

        base.HandleUnauthorizedRequest(filterContext);
    }
}

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

শেষটি, আমাদের কী করা উচিত - ক্লায়েন্টের পাশে HTTP 401/403 হ্যান্ডলিং যুক্ত করতে। কোডের সদৃশতা এড়াতে আমরা jQuery এ আজাক্সেরর ব্যবহার করতে পারি:

$(document).ajaxError(function (e, xhr) {
    if (xhr.status == 401)
        window.location = "/Account/Login";
    else if (xhr.status == 403)
        alert("You have no enough permissions to request this resource.");
});

ফলাফল -

  • যদি ব্যবহারকারী প্রমাণীকৃত না হয়, তবে তাকে কোনও এজেএক্স-কল করার পরে লগইন পৃষ্ঠায় পুনঃনির্দেশ করা হবে।
  • যদি ব্যবহারকারী প্রমাণীকৃত হয় তবে পর্যাপ্ত অনুমতি নেই তবে সে ব্যবহারকারী-বান্ধব এররার বার্তাটি দেখতে পাবে।
  • যদি ব্যবহারকারী সত্যায়িত হয় এবং পর্যাপ্ত অনুমতি থাকে তবে কোনও ত্রুটি নেই এবং যথারীতি এইচটিটিপি-অনুরোধটি চালানো হবে।

আমি এমভিসি এর মাধ্যমে লেখকের জন্য নতুন পরিচয় কাঠামোটি ব্যবহার করছি। এই সেটিংটি এমভিসি লগইন পাশাপাশি ওয়েবপিপি কলগুলি বাধা দেবে না?
টিম

5
যখন আমি এই উদাহরণটি যাচাই করেছিলাম এটি প্রদর্শিত হয় অনুমোদনযোগ্য বৈশিষ্ট্যটি ওয়েবএপি সংস্করণের পরিবর্তে এমভিসি সংস্করণ। তবে ওয়েবপি সংস্করণে ফর্মগুলি অদলবদল দমন করার বিকল্প নেই।
টিম

আমার অনুরোধটির একটি ইসএজাক্সরয়েস্ট পদ্ধতি নেই।
টিম

1
টিম এএসএক্সএক্সএক্সএকোয়েস্টের জন্য এটি দেখুন: brockallen.com/2013/10/27/… আপনি যদি শিরোনামগুলি সম্পাদনা না করে AngularJs ব্যবহার করছেন তবে আপনার কাছে "XMLHttpRequest" থাকবে না এবং হয় এটি যুক্ত করা বা অন্য কোনও কিছুর জন্য পরীক্ষা করা উচিত।
টিম

10

আপনি যদি Web APIআপনার MVCপ্রকল্পের মধ্যে থেকে চালাচ্ছেন তবে AuthorizeAttributeআপনার APIপদ্ধতিগুলিতে প্রয়োগ করার জন্য আপনাকে একটি কাস্টম তৈরি করতে হবে । মধ্যে IsAuthorized overrideআপনি বর্তমান দখল করতে প্রয়োজন HttpContextঅনুক্রমে ভালো ফেরৎ প্রতিরোধ:

    protected override bool IsAuthorized(HttpActionContext actionContext)
    {
        if (string.IsNullOrWhiteSpace(Thread.CurrentPrincipal.Identity.Name))
        {
            var response = HttpContext.Current.Response;
            response.SuppressFormsAuthenticationRedirect = true;
            response.StatusCode = (int)System.Net.HttpStatusCode.Forbidden;
            response.End();
        }

        return base.IsAuthorized(actionContext);
    }

8

নিজেই অ্যাজুরি অ্যাক্টিভ ডিরেক্টরি ইন্টিগ্রেশন ব্যবহার করে CookieAuthenticationমিডলওয়্যার ব্যবহার করে আমার পক্ষে কাজ হয়নি। আমাকে নিম্নলিখিতগুলি করতে হয়েছিল:

app.UseOpenIdConnectAuthentication(
    new OpenIdConnectAuthenticationOptions
    {
        ...
        Notifications = new OpenIdConnectAuthenticationNotifications
        {   
            ...         
            RedirectToIdentityProvider = async context =>
            {
                if (!context.Request.Accept.Contains("html"))
                {
                    context.HandleResponse();
                }
            },
            ...
        }
    });

যদি অনুরোধটি ব্রাউজার থেকে নিজেই আসে (এবং উদাহরণস্বরূপ কোনও এজেএক্স কল নয়) তবে স্বীকার করুন শিরোনামটি htmlএতে কোথাও স্ট্রিংটি ধারণ করবে । যখন ক্লায়েন্ট এইচটিএমএল গ্রহণ করবে কেবল তখনই আমি দরকারী কোনও পুনর্নির্দেশ বিবেচনা করব।

আমার ক্লায়েন্ট অ্যাপ্লিকেশনটি 401 ব্যবহারকারীকে অবহিত করতে পারে যে অ্যাপটির আর অ্যাক্সেস নেই এবং আবার লগইন করতে পুনরায় লোড করা দরকার to


এটি সম্পর্কিত প্রশ্নের জন্য প্রস্তাবিত সমাধানের সাথে খুব মিল: স্ট্যাকওভারফ্লো
গিলিয়াম লাহে

6

আমার ওয়েবেপি (ওউআইএন ব্যবহার করে) এর সাথে একটি এমভিসি 5 অ্যাপ্লিকেশন (সিস্টেম.ওয়েব) ছিল এবং কেবল ওয়েবএপি থেকে 401 টি প্রতিক্রিয়া 302 টি প্রতিক্রিয়াতে প্রতিরোধ করাতে চেয়েছিলাম।

আমার জন্য যা কাজ করেছিল তা হ'ল ওয়েবএপিআই অনুমোদনেরএকটি কাস্টমাইজড সংস্করণ তৈরি করা:

public class MyAuthorizeAttribute : System.Web.Http.AuthorizeAttribute
{
    protected override void HandleUnauthorizedRequest(HttpActionContext actionContext)
    {
        base.HandleUnauthorizedRequest(actionContext);
        HttpContext.Current.Response.SuppressFormsAuthenticationRedirect = true;
    }
}

এবং এটি স্ট্যান্ডার্ড WebApi AuthorizeAttribute এর জায়গায় ব্যবহার করতে। এমভিসি আচরণটি অপরিবর্তিত রাখার জন্য আমি মানক এমভিসি অথরিজ অ্যাট্রিবিউট ব্যবহার করেছি।


কাজ করে, তবে এখন আমার সমস্যা হয়েছে যে ক্লায়েন্ট 401 এর পরিবর্তে স্ট্যাটাস -1 পান
সেবাস্তিয়ান রোজাস

@ সেবাস্তিয়ানরোজাস আমি নিশ্চিত না যে এর কারণ কী হবে - SuppressFormsAuthenticationRedirect পতাকা নির্ধারণের ফলে এটি কেবল আমার জন্য বিদ্যমান 401 ফিরিয়ে আনতে পারে।
জোনো জব

3

কেবল নীগেট প্যাকেজটি ইনস্টল করুন

ইনস্টল-প্যাকেজ মাইক্রোসফ্ট.এএসপনেট.উইবএপিআই.উইন

WebApiConfig ফাইলে নিম্নলিখিত কোড লিখুন।

public static class WebApiConfig
{
    public static void Register(HttpConfiguration config)
    {
        //Web API configuration and services
        //Configure Web API to use only bearer token authentication.
        config.SuppressDefaultHostAuthentication();
        config.Filters.Add(new HostAuthenticationFilter(OAuthDefaults.AuthenticationType));
        config.Routes.MapHttpRoute(
            name: "DefaultApi",
            routeTemplate: "api/{controller}/{action}/{id}",
            defaults: new { id = RouteParameter.Optional }
        );
        config.Formatters.JsonFormatter.SupportedMediaTypes.Add(new MediaTypeHeaderValue("text/html"));
        config.Formatters.JsonFormatter.SupportedMediaTypes.Add(new MediaTypeHeaderValue("multipart/form-data"));
    }
}

আমাকে কেবল এই ফিল্টারটি যুক্ত করার দরকার ছিল এবং এটি config.Filters.Add(new HostAuthenticationFilter(OAuthDefaults.AuthenticationType));অন্যথায় কাজ User.Identity.IsAuthenticatedকরা সর্বদাfalse
রিকার্ডো সারাকিনো

1

আপনি যদি সামগ্রী-প্রকার == অ্যাপ্লিকেশন / জেএসন ধরতে চান তবে আপনি এই কোডটি ব্যবহার করতে পারেন:

private static bool IsAjaxRequest(IOwinRequest request)
    {
        IReadableStringCollection queryXML = request.Query;
        if ((queryXML != null) && (queryXML["X-Requested-With"] == "XMLHttpRequest"))
        {
            return true;
        }

        IReadableStringCollection queryJSON = request.Query;
        if ((queryJSON != null) && (queryJSON["Content-Type"] == "application/json"))
        {
            return true;
        }

        IHeaderDictionary headersXML = request.Headers;
        var isAjax = ((headersXML != null) && (headersXML["X-Requested-With"] == "XMLHttpRequest"));

        IHeaderDictionary headers = request.Headers;
        var isJson = ((headers != null) && (headers["Content-Type"] == "application/json"));

        return isAjax || isJson;

    }

শুভেচ্ছা !!


1

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

    actionContext.Response = new HttpResponseMessage()
    {
        StatusCode = HttpStatusCode.Forbidden,
        Content = new StringContent(unauthorizedMessage)
    };

1

লগইন পৃষ্ঠায় পুনর্নির্দেশগুলি এড়ানোর চেষ্টা করার পরে প্রচুর গোলমাল করার পরে, আমি বুঝতে পেরেছিলাম যে এটি আসলে অনুমোদনের বৈশিষ্ট্যের জন্য বেশ উপযুক্ত। এটি বলছে যে যাও এবং অনুমোদন পাও। অনুমোদিত নয় এমন অপি কলগুলির পরিবর্তে, আমি হ্যাকারদের কোনও তথ্য প্রকাশ না করার জন্য চেয়েছিলাম। এই উদ্দেশ্যটি অনুমোদন থেকে প্রাপ্ত নতুন বৈশিষ্ট্য যুক্ত করে সরাসরি অর্জন করা সহজ ছিল যা পরিবর্তে 404 ত্রুটি হিসাবে সামগ্রীটি আড়াল করে:

public class HideFromAnonymousUsersAttribute : AuthorizeAttribute
{
    protected override void HandleUnauthorizedRequest(HttpActionContext actionContext)
    {
         actionContext.Response = ActionContext.Request.CreateErrorResponse(HttpStatusCode.NotFound, "Access Restricted");
    }
}

0

ধন্যবাদ বন্ধুরা!

আমার ক্ষেত্রে, আমি কুনগল এবং শিবের উত্তরগুলি একত্রিত করেছি এবং এরকম কিছু পেয়েছি:

এপিআই ব্যতিক্রমগুলির জন্য কন্ট্রোলারের অনএক্সেপশন () হ্যান্ডলারে:

filterContext.ExceptionHandled = true;
//...
var response = filterContext.HttpContext.Response;
response.Headers.Add("Suppress-Redirect", "true");
response.SuppressFormsAuthenticationRedirect = true;

অ্যাপ স্টার্টআপ কনফিগার কোডে:

app.UseCookieAuthentication(new CookieAuthenticationOptions {
        AuthenticationType = DefaultAuthenticationTypes.ApplicationCookie,
        LoginPath = new PathString("/Account/Login"),
        Provider = new CookieAuthenticationProvider {
            OnValidateIdentity = ctx => {
                return validateFn.Invoke(ctx);
            },
            OnApplyRedirect = ctx =>
            {
                bool enableRedir = true;
                if (ctx.Response != null)
                {
                    string respType = ctx.Response.ContentType;
                    string suppress = ctx.Response.Headers["Suppress-Redirect"];
                    if (respType != null)
                    {
                        Regex rx = new Regex("^application\\/json(;(.*))?$",
                            RegexOptions.IgnoreCase);
                        if (rx.IsMatch(respType))
                        {
                            enableRedir = false;
                        }  
                    }
                    if ((!String.IsNullOrEmpty(suppress)) && (Boolean.Parse(suppress)))
                    {
                        enableRedir = false;
                    }
                }
                if (enableRedir)
                {
                    ctx.Response.Redirect(ctx.RedirectUri);
                }
            }
        }
    });

0

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

protected override void HandleUnauthorizedRequest(HttpActionContext actionContext)
{
    var httpContext = HttpContext.Current;
    if (httpContext == null)
    {
        base.HandleUnauthorizedRequest(actionContext);
        return;
    }

    actionContext.Response = httpContext.User.Identity.IsAuthenticated == false ?
        actionContext.Request.CreateErrorResponse(
      System.Net.HttpStatusCode.Unauthorized, "Unauthorized") :
       actionContext.Request.CreateErrorResponse(
      System.Net.HttpStatusCode.Forbidden, "Forbidden");

    httpContext.Response.SuppressFormsAuthenticationRedirect = true;
    httpContext.Response.End();
}

-1

এমভিসি 5-তে ডট নেট ফ্রেমওয়ার্ক 4.5 এর সাথে আমরা "অ্যাপ্লিকেশন / জেএসন, প্লিন্ট টেক্সট .." পেয়েছি "স্বীকার করুন" শিরোনামের অধীনে নিম্নলিখিতগুলির মতো ব্যবহার করা ভাল হবে:

isJson = headers["Content-Type"] == "application/json" || headers["Accept"].IndexOf("application/json", System.StringComparison.CurrentCultureIgnoreCase) >= 0;
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.