asp.net mvc - ASP.NET এমভিসি শুধুমাত্র উৎপাদন উত্পাদনের প্রয়োজন




asp.net-mvc visual-studio (10)

আমি কোনও পদ্ধতিতে পাঠানো থেকে অনিরাপদ HTTP অনুরোধগুলি আটকানোর জন্য RequireHttpsAttribute ব্যবহার করতে চাই।

সি শার্প

[RequireHttps] //apply to all actions in controller
public class SomeController 
{
    [RequireHttps] //apply to this action only
    public ActionResult SomeAction()
    {
        ...
    }
}

ভিবি

<RequireHttps()> _
Public Class SomeController

    <RequireHttps()> _
    Public Function SomeAction() As ActionResult
        ...
    End Function

End Class

দুর্ভাগ্যবশত, ASP.NET ডেভেলপমেন্ট সার্ভার HTTPS সমর্থন করে না।

আমি কিভাবে আমার ASP.NET এমভিসি অ্যাপ্লিকেশনটি উত্পাদন পরিবেশে প্রকাশিত হলে RequHttps ব্যবহার করতে পারি, কিন্তু এটি যখন ASP.NET ডেভেলপমেন্ট সার্ভারে আমার ডেভেলপমেন্ট ওয়ার্কস্টেশনে চলবে না?


Azure এবং MVC এ RickAndMSFT এ রিক অ্যান্ডারসন দ্বারা আজকের গ্যাপ পূরণ করে এই পোস্টটি পড়ুন

blogs.msdn.com/b/rickandy/archive/2011/04/22/…


RequireHttps থেকে deriving একটি ভাল পদ্ধতির।

পাশাপাশি ইস্যুটি সম্পূর্ণরূপে সরানোর জন্য, আপনি নিজের স্থানীয় মেশিনে আইআইএসটি স্ব স্ব স্বাক্ষরিত শংসাপত্রের সাথেও ব্যবহার করতে পারেন। আইআইএস বিল্ট-ইন ওয়েব সার্ভারের চেয়ে দ্রুত, এবং আপনার সুবিধা পরিবেশের মতো আরও বেশি সুবিধা রয়েছে।

VS2010 এবং IIS Express এর সাথে স্থানীয় HTTPS বাস্তবায়নের কয়েকটি উপায়ে স্কট হানসেলম্যানের দুর্দান্ত সম্পদ রয়েছে।


আপনি যদি ওভাররাইড করতে পারেন - এটি করুন। আপনি যদি না করতে পারেন - MVC উত্সগুলির সাথে আসে, কেবল সূত্রগুলি গ্রহণ করুন এবং আপনার নিজস্ব [ForceHttps] বৈশিষ্ট্যটি তৈরি করুন যা IsLocal টি পরীক্ষা করে।


উদ্বেগ অনুসন্ধানের পর, আমি আইআইএস এক্সপ্রেস এবং কন্ট্রোলার ক্লাসের অনঅনুহরণ পদ্ধতির একটি ওভার্রাইডের সাথে এই সমস্যাটির সমাধান করতে সক্ষম হয়েছিলাম (রেফার # 1)। আমি হানসেলম্যান (রেফার # ২) দ্বারা প্রস্তাবিত রুট দিয়ে চলে গেছি। যাইহোক, দুটি কারণের কারণে আমি এই দুটি সমাধানগুলির সাথে সন্তুষ্ট ছিলাম না: 1. রেফার # 1 এর অননুমোদিতকরণ শুধুমাত্র ক্রমানুসার পর্যায়ে কাজ করে, কন্ট্রোলার বর্গ স্তরে নয়। রেফার # 2 এর জন্য অনেক সেটআপ দরকার (মেকার্টের জন্য Win7 SDK ), নেটস্কেস কমান্ড, এবং, পোর্ট 80 এবং পোর্ট 443 ব্যবহার করার জন্য, আমি প্রশাসক হিসাবে VS2010 চালু করতে হবে, যা আমি ভাঙ্গা করেছি।

সুতরাং, আমি এই সমাধানটি নিয়ে এসেছি যা নিম্নলিখিত শর্তগুলির সাথে সরলতার উপর দৃষ্টি নিবদ্ধ করে:

  1. আমি কনট্রোলার ক্লাস বা অ্যাকশন লেভেলে RequireHttps attbbute ব্যবহার করতে সক্ষম হতে চাই

  2. আমি যখন RequHttps বৈশিষ্ট্য উপস্থিত থাকি তখন এমভিসিটি HTTPS ব্যবহার করতে চাই এবং এটি অনুপস্থিত থাকলে HTTP ব্যবহার করুন

  3. আমি ভিজুয়াল স্টুডিও প্রশাসক হিসাবে চালাতে চাই না

  4. আমি আইআইএস এক্সপ্রেস দ্বারা নির্ধারিত যেকোন HTTP এবং HTTPS পোর্ট ব্যবহার করতে সক্ষম হতে চাই (নোট # 1 দেখুন)

  5. আমি আইআইএস এক্সপ্রেস স্ব স্বাক্ষরকৃত SSL সার্টিফিকেট পুনঃব্যবহার করতে পারি, এবং যদি আমি অবৈধ SSL প্রম্পট দেখতে না পাওয়ি তবে আমার কোনও পার্থক্য নেই

  6. আমি ডিভি, পরীক্ষা, এবং উত্পাদনটি একই কোড বেস এবং একই বাইনারি এবং অতিরিক্ত সেটআপ থেকে স্বাধীন (যেমন ন্যেটশ, এমএমসি সার্টে স্ন্যাপ-ইন ইত্যাদি ব্যবহার করে) হিসাবে সম্ভব

এখন, ব্যাকগ্রাউন্ড এবং ব্যাখ্যা আউট ব্যাখ্যা সঙ্গে, আমি আশা করি এই কোড কেউ সাহায্য করবে এবং কিছু সময় বাঁচাতে। মূলত, কন্ট্রোলার থেকে উত্তরাধিকারী একটি বেস কন্ট্রোলার শ্রেণী তৈরি করুন এবং এই বেস ক্লাস থেকে আপনার নিয়ামক ক্লাসগুলি অর্জন করুন। যেহেতু আপনি এই পর্যন্ত পড়েছেন, আমি অনুমান করছি যে আপনি কীভাবে এটি করবেন তা জানুন। তাই, শুভ কোডিং!

দ্রষ্টব্য # 1: এটি একটি কার্যকর ফাংশন 'getConfig' ব্যবহার করে অর্জন করা হয় (কোড দেখুন)

রেফার # 1: http://puredotnetcoder.blogspot.com/2011/09/requirehttps-attribute-in-mvc3.html

রেফার # ২: http://www.hanselman.com/blog/ ওয়ার্কিং উইথস্লেট ডেভেলপমেন্টটাইমআইএসএআইএসআইআইআইআইআইএসএস এক্সপ্রেস.এসপিএক্স

========== বেস কন্ট্রোলারের কোড ===================

     #region Override to reroute to non-SSL port if controller action does not have RequireHttps attribute to save on CPU 
    // By L. Keng, 2012/08/27
    // Note that this code works with RequireHttps at the controller class or action level.
    // Credit: Various .com posts and http://puredotnetcoder.blogspot.com/2011/09/requirehttps-attribute-in-mvc3.html
    protected override void OnAuthorization(AuthorizationContext filterContext)
    {
        // if the controller class or the action has RequireHttps attribute
        var requireHttps = (filterContext.ActionDescriptor.ControllerDescriptor.GetCustomAttributes(typeof(RequireHttpsAttribute), true).Count() > 0 
                            || filterContext.ActionDescriptor.GetCustomAttributes(typeof(RequireHttpsAttribute), true).Count() > 0);
        if (Request.IsSecureConnection)
        {
            // If request has a secure connection but we don't need SSL, and we are not on a child action   
            if (!requireHttps && !filterContext.IsChildAction)
            {
                var uriBuilder = new UriBuilder(Request.Url)
                {
                    Scheme = "http",
                    Port = int.Parse(getConfig("HttpPort", "80")) // grab from config; default to port 80
                };
                filterContext.Result = this.Redirect(uriBuilder.Uri.AbsoluteUri);
            }
        }
        else
        {
            // If request does not have a secure connection but we need SSL, and we are not on a child action   
            if (requireHttps && !filterContext.IsChildAction)
            {
                var uriBuilder = new UriBuilder(Request.Url)
                {
                    Scheme = "https",
                    Port = int.Parse(getConfig("HttpsPort", "443")) // grab from config; default to port 443
                };
                filterContext.Result = this.Redirect(uriBuilder.Uri.AbsoluteUri);
            }
        }
        base.OnAuthorization(filterContext);
    }
    #endregion

    // a useful helper function to get appSettings value; allow caller to specify a default value if one cannot be found
    internal static string getConfig(string name, string defaultValue = null)
    {
        var val = System.Configuration.ConfigurationManager.AppSettings[name];
        return (val == null ? defaultValue : val);
    }

============== শেষ কোড ================

Web.Release.Config, HttpPort এবং HttpsPort (ডিফল্ট 80 এবং 443 ব্যবহার করার জন্য) মুছে ফেলার জন্য নিচেরটি যোগ করুন।

<appSettings>
<add key="HttpPort" value="" xdt:Transform="SetAttributes" xdt:Locator="Match(key)"/>
<add key="HttpsPort" value="" xdt:Transform="SetAttributes" xdt:Locator="Match(key)"/>
</appSettings>

এক সমাধান আপনি উত্পাদন পাশাপাশি উন্নয়ন ওয়ার্কস্টেশন ব্যবহার করতে পারেন। এটি web.config এ অ্যাপ্লিকেশন সেটিংস থেকে আপনার বিকল্পের উপর ভিত্তি করে

<appSettings>
     <!--Use SSL port 44300 in IIS Express on development workstation-->
     <add key="UseSSL" value="44300" />
</appSettings>

আপনি যদি এসএসএল ব্যবহার করতে চান না চাবি মুছে ফেলুন। আপনি যদি স্ট্যান্ডার্ড SSL পোর্ট 443 ব্যবহার করেন তবে মানটি মুছুন অথবা 443 উল্লেখ করুন।

তারপর আপনার শর্ত যত্ন নেয় যে RequireHttpsAttribute কাস্টম বাস্তবায়ন ব্যবহার করুন। এটি আসলে RequHttps থেকে প্রাপ্ত এবং অবস্থার যোগ ছাড়া বেস পদ্ধতির একই বাস্তবায়ন ব্যবহার করে।

public class RequireHttpsConditional : RequireHttpsAttribute
{
    protected override void HandleNonHttpsRequest(AuthorizationContext filterContext)
    {
        var useSslConfig = ConfigurationManager.AppSettings["UseSSL"];
        if (useSslConfig != null)
        {
            if (!string.Equals(filterContext.HttpContext.Request.HttpMethod, "GET", StringComparison.OrdinalIgnoreCase))
            {
                throw new InvalidOperationException("The requested resource can only be accessed via SSL.");
            }

            var request = filterContext.HttpContext.Request;
            string url = null;
            int sslPort;

            if (Int32.TryParse(useSslConfig, out sslPort) && sslPort > 0)
            {
                url = "https://" + request.Url.Host + request.RawUrl;

                if (sslPort != 443)
                {
                    var builder = new UriBuilder(url) {Port = sslPort};
                    url = builder.Uri.ToString();
                }
            }

            if (sslPort != request.Url.Port)
            {
                filterContext.Result = new RedirectResult(url);
            }
        }
    }
}

AccountController মধ্যে LogOn পদ্ধতি সাজাইয়া ভুলবেন না

[RequireHttpsConditional]
[HttpPost]
public ActionResult LogOn(LogOnModel model, string returnUrl)

এবং https এ ফর্মটি পোস্ট করার জন্য আপনার LogOn ভিউতে এটির মত কিছু।

<% using (Html.BeginFormSecure("LogOn", "Account", new { ReturnUrl = Request.QueryString["ReturnUrl"] }, Request.IsSecureConnection, Request.Url)) { %>

একটি কাস্টম গুণাবলী মধ্যে RequireHttps বৈশিষ্ট্য উত্তরাধিকারী সম্পর্কে কিভাবে। তারপরে, আপনার কাস্টম এ্যাট্রিবিউটের ভিতরে, স্থানীয় মেশিন থেকে অনুরোধ আসছে কিনা তা দেখতে বর্তমান অনুরোধের IsLocal সম্পত্তিটি দেখুন। যদি এটি হয়, তাহলে বেস কার্যকারিতা প্রয়োগ করবেন না। অন্যথায়, বেস অপারেশন কল।


এটি আমার জন্য সবচেয়ে পরিষ্কার উপায় ছিল। আমার App_Start\FilterConfig.cs ফাইলে। রিলিজ চালানো যাবে না যদিও আর বিল্ড।

... 
public static void RegisterGlobalFilters(GlobalFilterCollection filters)
{
        if (!Web.HttpContext.Current.IsDebuggingEnabled) {
            filters.Add(new RequireHttpsAttribute());   
        }
        ...
}

অন্যথায়, আপনি যখন আপনার কাস্টম ত্রুটি পৃষ্ঠাটি চালু থাকে তখন এটি কেবল https এর জন্য প্রয়োজন হতে পারে।

... 
public static void RegisterGlobalFilters(GlobalFilterCollection filters)
{
        if (Web.HttpContext.Current.IsCustomErrorEnabled) {
            filters.Add(new RequireHttpsAttribute());   
        }
        ...
}

এমভিসি 3 এর জন্য আমি নিজের ফিল্টারপ্রভাইডার যুক্ত করেছি (এখানে পাওয়া কোডের উপর ভিত্তি করে: গ্লোবাল এবং শর্তাধীন ফিল্টারগুলি , অন্যান্য জিনিসগুলির মধ্যে (স্থানীয় ব্যবহারকারীদের জন্য ডিবাগ তথ্য প্রদর্শন করা ইত্যাদি), HttpContext.Request.IsLocal == false হলে HttpContext.Request.IsLocal == false সাথে সমস্ত ক্রিয়াকলাপ সাজিয়ে দেবে।


জোয়েল উল্লেখ করেছেন যে আপনি #if !DEBUG নির্দেশ ব্যবহার করে #if !DEBUG পরিবর্তন করতে পারেন।

আমি ঠিক করেছি যে আপনি web.config ফাইল সংকলন উপাদানটিতে DEBUG প্রতীকটির মান পরিবর্তন করতে পারেন। আশা করি এইটি কাজ করবে.


যদি কেউ C # সংস্করণের প্রয়োজন হয়:

using System;
using System.Web.Mvc;

namespace My.Utils
{
    public class MyRequireHttpsAttribute : RequireHttpsAttribute
    {
        public override void OnAuthorization(AuthorizationContext filterContext)
        {
            if (filterContext == null)
            {
                throw new ArgumentNullException("filterContext");
            }

            if (filterContext.HttpContext != null && filterContext.HttpContext.Request.IsLocal)
            {
                return;
            }

            base.OnAuthorization(filterContext);
        }
    }
}




https