HTTPListener অ্যাক্সেস অস্বীকৃত


179

আমি সি # তে একটি HTTP সার্ভার লিখছি।

আমি যখন ফাংশনটি সম্পাদন করার চেষ্টা করি তখন আমার HttpListener.Start()একটি HttpListenerExceptionবক্তব্য পাওয়া যায়

"অ্যাক্সেস অস্বীকৃত"।

আমি যখন উইন্ডোজ in-এ অ্যাডমিন মোডে অ্যাপটি চালনা করি তখন এটি ঠিকঠাক কাজ করে।

আমি কি এডমিন মোড ছাড়াই এটি চালাতে পারি? যদি হ্যাঁ কিভাবে? যদি না হয় তবে কীভাবে আমি অ্যাপ্লিকেশনটি চালানো শুরু করার পরে অ্যাডমিন মোডে পরিবর্তন করতে পারি?

using System;
using System.Net;

namespace ConsoleApplication1
{
    class Program
    {
        private HttpListener httpListener = null;

        static void Main(string[] args)
        {
            Program p = new Program();
            p.Server();
        }

        public void Server()
        {
            this.httpListener = new HttpListener();

            if (httpListener.IsListening)
                throw new InvalidOperationException("Server is currently running.");

            httpListener.Prefixes.Clear();
            httpListener.Prefixes.Add("http://*:4444/");

            try
            {
                httpListener.Start(); //Throws Exception
            }
            catch (HttpListenerException ex)
            {
                if (ex.Message.Contains("Access is denied"))
                {
                    return;
                }
                else
                {
                    throw;
                }
            }
        }
    }
}

কেউ যদি ত্রুটি এড়াতে চান তবে তিনি এটি টিসিপিলিস্টারের সাহায্যে লেখার চেষ্টা করতে পারেন। এটির জন্য প্রশাসনিক সুযোগ
ভ্লাদ

আমি একই ইস্যুটির মুখোমুখি, ভিজ্যুয়াল স্টুডিও ২০০৮ + উইন্ডোজ in-তে, এটি 'অ্যাক্সেস অস্বীকৃত' ত্রুটি তৈরি করে, সমাধানের সমাধানের জন্য অ্যাডমিন মোডে ভিজ্যুয়াল স্টুডিও
মার্ক খোর

উত্তর:


307

হ্যাঁ আপনি নন-অ্যাডমিন মোডে এইচটিটিপিপ্লাইনার চালাতে পারেন। আপনাকে যা করতে হবে তা হ'ল নির্দিষ্ট ইউআরএলকে অনুমতি প্রদান করা। যেমন

netsh http add urlacl url=http://+:80/MyUri user=DOMAIN\user

ডকুমেন্টেশন এখানে


48
এটি সহায়ক, তবে সম্পূর্ণতার জন্য এই কোডের এই লাইনে নির্দিষ্ট ইউআরএল: httpListener.Prefixes.Add("http://*:4444/");অবশ্যই netshকমান্ডের সাথে একটির সাথে অবশ্যই মিলবে । উদাহরণস্বরূপ, আমার কাছে ছিল httpListener.Prefixes.Add("http://127.0.0.1:80/");এবং আপনার কাছে একই netshকমান্ডটি রয়েছে এবং এখনও এইচটিটিপিপ্লাইস্টারঅ্যাক্সপশনটি নিক্ষেপ করা হবে। httpListener.Prefixes.Add("http://+:80/");আপনার সাহায্যের জন্য আমাকে ধন্যবাদ বদলানো দরকার ড্যারিল মিলার, কারণ আপনি আমাকে এটি সন্ধানের সঠিক পথে পেয়েছেন!
সাইক্লোপজ

10
এবং "মাইআউরি" খালি থাকলে পিছনের স্ল্যাশটি ভুলে যাবেন না, তবে আপনি একটি The parameter is incorrectত্রুটি পাবেন। উদাহরণ:url=http://+:80/
ইগোর ব্রেজক

14
এমনকি প্রশাসনিক প্রশাসনিক ব্যবহারকারীর পক্ষে কি এটি করার কোনও উপায় আছে http://localhost:80/? আমার কাছে একটি ডেস্কটপ অ্যাপ্লিকেশন রয়েছে যা এই জাতীয় ইউআরএলটিতে একটি অনুরোধ গ্রহণ করা প্রয়োজন এবং এটি কেবলমাত্র একটি উদ্দেশ্যে, প্রশাসক এটি 50 ডেস্কটপগুলিতে এটি ইনস্টল করা প্রয়োজন বলে লজ্জাজনক বলে মনে হয়।
জন স্যান্ডার্স

5
দৃশ্যত না. ডকুমেন্টেশন পৃষ্ঠাতে উচ্চতা বা প্রশাসনিক সুবিধাগুলির প্রয়োজনের কোনও উল্লেখ নেই। সুতরাং এটি সহজেই অনুমান করা যায় যে এটি "স্মার্ট" টিসিপিপ্লাইটার হিসাবে কাজ করবে, যখন বাস্তবে এটি ব্যবহার না করার বড় কারণ রয়েছে - তবে এটি দলিল নয় isn't
ডেভিড ফোর্ড


27

আমি কি এডমিন মোড ছাড়াই এটি চালাতে পারি? যদি হ্যাঁ কিভাবে? যদি না হয় তবে কীভাবে আমি অ্যাপ্লিকেশনটি চালানো শুরু করার পরে অ্যাডমিন মোডে পরিবর্তন করতে পারি?

আপনি পারবেন না, এটি উন্নত সুবিধাগুলি দিয়ে শুরু করতে হবে। আপনি এটি runasক্রিয়া দিয়ে পুনরায় চালু করতে পারেন যা ব্যবহারকারীকে অ্যাডমিন মোডে স্যুইচ করার অনুরোধ জানাবে

static void RestartAsAdmin()
{
    var startInfo = new ProcessStartInfo("yourApp.exe") { Verb = "runas" };
    Process.Start(startInfo);
    Environment.Exit(0);
}

সম্পাদনা: আসলে, এটি সত্য নয়; HTTPListener উন্নত সুবিধা ছাড়াই চলতে পারে, তবে আপনি যে ইউআরএলটি শুনতে চান তাতে আপনার অনুমতি দেওয়া দরকার। দেখুন Darrel মিলারের উত্তর বিস্তারিত জানার জন্য।


আপনি দয়া করে আমাকে ব্যাখ্যা করতে পারেন কেন আমাকে উন্নত সুবিধা দিয়ে শুরু করতে হবে?
র‌্যান্ডাল ফ্ল্যাগ

আপনার এই লাইনটি 'startInfo.UseShellExecute = false;' যুক্ত করতে হবে; 'প্রক্রিয়া.স্টার্ট (startInfo) এর আগে;'
র‌্যান্ডাল ফ্ল্যাগ

@ র্যান্ডল: কারণ উইন্ডোজ কীভাবে এটি কাজ করে ... কোনও প্রক্রিয়া চলমান অবস্থায় অ্যাডমিন মোডে স্যুইচ করতে পারে না। UseShellExecute সম্পর্কিত: এটি আপনি কী চালাচ্ছেন তার উপর নির্ভর করে। আমি আমার কোডটি "notepad.exe" দিয়ে পরীক্ষা করেছি, এটি UseShellExecute = মিথ্যা ব্যতীত সূক্ষ্মভাবে কাজ করে
টমাস

ধন্যবাদ। UseShellExecute সম্পর্কে: আমি পোস্ট করা কোডটি চালানোর চেষ্টা করেছি। অন্য সমস্যাটি হ'ল কোনও কারণে এটি আমাকে একবার জিজ্ঞাসা করেছিল আমি প্রশাসক হিসাবে চালাতে চাই এবং অন্য কোনও সময় এটি জিজ্ঞাসা করে না। আমি আবার চালু করেছি, ডিবাগ করেছিলাম তা নিশ্চিত হয়ে যায় যে এটি সেখানে যায় এবং কিছুই হয় না। কোনও পরামর্শ?
র‌্যান্ডাল ফ্ল্যাগ

1
@ থমাস নন-অ্যাডমিন মোডে এইচটিপিপ্লাইস্টার চালাতে কোনও সমস্যা নেই।
ড্যারেল মিলার

23

আপনি যদি http://localhost:80/উপসর্গ হিসাবে ব্যবহার করেন, আপনি প্রশাসনিক সুযোগ-সুবিধার কোনও প্রয়োজন ছাড়াই HTTP অনুরোধগুলি শুনতে পারবেন।


2
আপনি কিছু উদাহরণ কোড পোস্ট করতে পারেন? আমি কেবল এটি দিয়ে চেষ্টা করেছি http://localhost:80/এবং একটি "অ্যাক্সেস অস্বীকৃত" পেয়েছি।
জন স্যান্ডার্স

2
দুঃখিত, এটি কাজ করে না বলে মনে হচ্ছে। আপনি প্রশাসক হিসাবে চালাচ্ছেন কিনা তা দয়া করে পরীক্ষা করে দেখুন, যা সাধারণ ক্ষেত্রে হওয়া উচিত নয়।
জোনো

এটি যদি কাজ করে তবে আমি এটিকে উইন্ডোজ বাগ হিসাবে বিবেচনা করব। আপনি উইন্ডোজ সম্পর্কে যা ভাবেন তা বিবেচনা না করেই আমি এটি খুব প্রাথমিক স্তরের বলে ধরে নিই যে খুব সম্ভবত তারা সঠিকভাবে পরিচালনা করতে পারেনি।
হোইজুই

26
2 বছরেরও বেশি পরে, এটি এখন উইন্ডোজ সার্ভার 2008 আর 2 তে নেট নেট ফ্রেমওয়ার্ক 4.5 নিয়ে আমার জন্য কাজ করে। httpListener.Prefixes.Add("http://*:4444/");আসলে একটি Access Deniedত্রুটি দেখায় তবে httpListener.Prefixes.Add("http://localhost:4444/");কোনও সমস্যা ছাড়াই কাজ করে। দেখে মনে হচ্ছে মাইক্রোসফ্ট localhostএই বিধিনিষেধ থেকে বাদ পড়েছে। মজার বিষয় হল, httpListener.Prefixes.Add("http://127.0.0.1:4444/");এখনও একটি অ্যাক্সেস অস্বীকৃত ত্রুটি দেখায়, তাই কেবলমাত্র কাজটি হ'লlocalhost:{any port}
টনি

1
@ টনি ধন্যবাদ আপনার মন্তব্যটি আসলে আমার জন্য সবচেয়ে মূল্যবান ছিল। আমার বেশ কয়েকটি কনফিগারেশনে "127.0.0.1" ছিল। কিউএ জানিয়েছে যে এটি উইন্ডোজ ৮.১ এ কাজ করছে না তবে উইন্ডোজ 10 এ ছিল ঠিক জরিমানা (এবং আমি এটি উইন 10 এ নিজেই পরীক্ষা করেছি)। অদ্ভুতভাবে, দেখে মনে হচ্ছে মাইক্রোসফ্ট সবাই উইন 10 এ 127.0.0.1 ব্যবহার করার মঞ্জুরি দিয়েছে তবে 8.1 নয় (এবং সম্ভবত পূর্ববর্তী সংস্করণগুলি), তবে যথেষ্ট নিশ্চিত, লোকালহোস্ট ঠিক আছে। ধন্যবাদ
অ্যাডাম প্লোচার

20

বাক্যবিন্যাসটি আমার পক্ষে ভুল ছিল, আপনার অবশ্যই উদ্ধৃতিগুলি অন্তর্ভুক্ত করতে হবে:

netsh http add urlacl url="http://+:4200/" user=everyone

অন্যথায় আমি "প্যারামিটারটি ভুল" পেয়েছি


4
আপনি যদি /ইউআরএলটিতে
কোনও অনুবর্তন

13

আপনি "ব্যবহারকারী = প্রত্যেককে" পতাকাটি ব্যবহার করতে চাইলে আপনার এটিকে আপনার সিস্টেমের ভাষাতে সামঞ্জস্য করতে হবে। ইংরেজিতে এটি উল্লেখ করা হয়েছে:

netsh http add urlacl url=http://+:80/ user=Everyone

জার্মান ভাষায় এটি হবে:

netsh http add urlacl url=http://+:80/ user=Jeder

1
স্প্যানিশ-ভাষা সিস্টেমে, ব্যবহার করুন: ব্যবহারকারী = টোডোস
রডরিগো রডরিগস

এছাড়াও, আমার অন্য একটি উত্তর হিসাবে উল্লিখিত হিসাবে, ইউআরএল উদ্ধৃতিতে রাখা প্রয়োজন।
কার্স্টেন ফারহম্যান

10

বিকল্প হিসাবে যার জন্য উচ্চতা বা নেট প্রয়োজন হয় না আপনি উদাহরণস্বরূপ TcpListenerও ব্যবহার করতে পারেন।

নিম্নোক্ত এই নমুনার একটি পরিবর্তিত উদ্ধৃতাংশ: https://github.com/googlesamples/oauth-apps-for-windows/tree/master/OAuthDesktopApp

// Generates state and PKCE values.
string state = randomDataBase64url(32);
string code_verifier = randomDataBase64url(32);
string code_challenge = base64urlencodeNoPadding(sha256(code_verifier));
const string code_challenge_method = "S256";

// Creates a redirect URI using an available port on the loopback address.
var listener = new TcpListener(IPAddress.Loopback, 0);
listener.Start();
string redirectURI = string.Format("http://{0}:{1}/", IPAddress.Loopback, ((IPEndPoint)listener.LocalEndpoint).Port);
output("redirect URI: " + redirectURI);

// Creates the OAuth 2.0 authorization request.
string authorizationRequest = string.Format("{0}?response_type=code&scope=openid%20profile&redirect_uri={1}&client_id={2}&state={3}&code_challenge={4}&code_challenge_method={5}",
    authorizationEndpoint,
    System.Uri.EscapeDataString(redirectURI),
    clientID,
    state,
    code_challenge,
    code_challenge_method);

// Opens request in the browser.
System.Diagnostics.Process.Start(authorizationRequest);

// Waits for the OAuth authorization response.
var client = await listener.AcceptTcpClientAsync();

// Read response.
var response = ReadString(client);

// Brings this app back to the foreground.
this.Activate();

// Sends an HTTP response to the browser.
WriteStringAsync(client, "<html><head><meta http-equiv='refresh' content='10;url=https://google.com'></head><body>Please close this window and return to the app.</body></html>").ContinueWith(t =>
{
    client.Dispose();
    listener.Stop();

    Console.WriteLine("HTTP server stopped.");
});

// TODO: Check the response here to get the authorization code and verify the code challenge

পড়ার এবং লেখার পদ্ধতিগুলি হ'ল:

private string ReadString(TcpClient client)
{
    var readBuffer = new byte[client.ReceiveBufferSize];
    string fullServerReply = null;

    using (var inStream = new MemoryStream())
    {
        var stream = client.GetStream();

        while (stream.DataAvailable)
        {
            var numberOfBytesRead = stream.Read(readBuffer, 0, readBuffer.Length);
            if (numberOfBytesRead <= 0)
                break;

            inStream.Write(readBuffer, 0, numberOfBytesRead);
        }

        fullServerReply = Encoding.UTF8.GetString(inStream.ToArray());
    }

    return fullServerReply;
}

private Task WriteStringAsync(TcpClient client, string str)
{
    return Task.Run(() =>
    {
        using (var writer = new StreamWriter(client.GetStream(), new UTF8Encoding(false)))
        {
            writer.Write("HTTP/1.0 200 OK");
            writer.Write(Environment.NewLine);
            writer.Write("Content-Type: text/html; charset=UTF-8");
            writer.Write(Environment.NewLine);
            writer.Write("Content-Length: " + str.Length);
            writer.Write(Environment.NewLine);
            writer.Write(Environment.NewLine);
            writer.Write(str);
        }
    });
}

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

1
এটি লক্ষণীয় যে উপরের কোডটিতে বাগ রয়েছে যদিও। প্রথমত ইউটিএফ 8 এর সাথে স্ট্রিম রাইটার ব্যবহার করা কিছু ব্রাউজারে সমস্যার কারণ হয়ে থাকে, আমি বিএমএলের আউটপুট বা এরকম কিছু হওয়ার কারণে অনুমান করছি। আমি এএসসিআইআইতে পরিবর্তন করেছি এবং সবকিছু ঠিক আছে। স্ট্রিমে পড়ার জন্য ডেটা উপলব্ধ হওয়ার জন্য অপেক্ষা করার জন্য আমি কিছু কোড যুক্ত করেছি কারণ এটি কখনও কখনও কোনও ডেটা ফেরত না।
ম্যাকি

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

2
ASCII ব্যবহার না করে নিম্নলিখিত কন্সট্রাক্টর ব্যবহার করা উচিত new UTF8Encoding(false), যা একটি বিওএম নির্গমন করতে অক্ষম করে। আমি ইতিমধ্যে উত্তরে এটি পরিবর্তন করেছি
সেবাস্তিয়ান

আমি গৃহীত উত্তরের চেয়ে এই সমাধানটিকে পছন্দ করি। নেট চালানো হ্যাকের মতো মনে হচ্ছে। এটি একটি কঠিন প্রোগ্রামেটিক সমাধান। ধন্যবাদ!
জিম গোমেস

7

আপনি যদি আপনার প্রকল্পে অ্যাপ্লিকেশন ম্যানিফেস্ট যুক্ত করেন তবে আপনি প্রশাসক হিসাবে আপনার আবেদন শুরু করতে পারেন।

আপনার প্রকল্পে কেবল নতুন আইটেম যুক্ত করুন এবং "অ্যাপ্লিকেশন ম্যানিফেস্ট ফাইল" নির্বাচন করুন। <requestedExecutionLevel>উপাদানটি এতে পরিবর্তন করুন :

<requestedExecutionLevel level="requireAdministrator" uiAccess="false" />

7

ডিফল্টরূপে উইন্ডোজ নিম্নলিখিত উপসর্গটি সংজ্ঞায়িত করে যা প্রত্যেকের জন্য উপলব্ধ: http: // +: 80 / অস্থায়ী_লিস্টেন_এড্রেস /

সুতরাং আপনি এর HttpListenerমাধ্যমে নিবন্ধন করতে পারেন :

Prefixes.Add("http://+:80/Temporary_Listen_Addresses/" + Guid.NewGuid().ToString("D") + "/";

এটি কখনও কখনও স্কাইপ এর মতো সফ্টওয়্যার নিয়ে সমস্যা সৃষ্টি করে যা ডিফল্টভাবে 80 পোর্টটি ব্যবহারের চেষ্টা করবে।


1
স্কাইপ ছিল অপরাধী। আমি পোর্ট পরিবর্তন না 80 হতে হবে এবং এটা কাজ করে।
GoTo

5
httpListener.Prefixes.Add("http://*:4444/");

আপনি "*" ব্যবহার করেন যাতে আপনি নিম্নলিখিত সিএমডি অ্যাডমিন হিসাবে কার্যকর করেন

netsh http add urlacl url=http://*:4444/ user=username

কোন ব্যবহার +, অবশ্যই * ব্যবহার করা উচিত, কারণ আপনি *: 4444 spec নির্দিষ্ট করেছেন ~

https://msdn.microsoft.com/en-us/library/system.net.httplistener.aspx


এটা আমার জন্য ছিল। এটি আমার পক্ষে কাজ করেছে.Add("http://+:9000/")
জন গিয়েজেন

2

আমিও অনুরূপ সমস্যার মুখোমুখি হয়েছি I যদি আপনি ইতিমধ্যে ইউআরএল সংরক্ষণ করেছেন তবে আপনাকে প্রথমে নন অ্যাডমিন মোডে চালানোর জন্য ইউআরএলটি মুছতে হবে অন্যথায় এটি অ্যাক্সেসের সাথে অস্বীকৃত ত্রুটিযুক্ত will

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