简体   繁体   English

用于 c# REST API 中的本机/桌面应用程序的 Keycloack,无法正常工作还是我遗漏了什么?

[英]Keycloack for native /desktop application in c# REST APIs, not working properly or am I missing something?

I can get the authorization code and access token by a keycloak endpoint ONLY when I already have the browser opened and already did the login, otherwise the code fails to get the authorization code.只有当我已经打开浏览器并已经登录时,我才能通过 keycloak 端点获取授权码和访问令牌,否则代码无法获取授权码。

so considering I implement this logic at the application start ( it's not definitive ) , I have to run it 2 times to get code and then the token.所以考虑到我在应用程序开始时实现了这个逻辑(它不是确定的),我必须运行它 2 次才能获取代码,然后是令牌。

I just use rest APIs because I can not find an understandable keycloak library to use for desktop / native applications.我只使用rest API,因为我找不到可用于桌面/本机应用程序的可理解的keycloak库。

this is my code:这是我的代码:

public static async  Task<string>  GetTokenAsync()
    {
 
        string redirectURI = string.Format("http://{0}:{1}/", "localhost", GetRandomUnusedPort());
        string RedirectURIWithoutLastSlash = redirectURI.TrimEnd('/');
 
 
        string code = await GetCodeForAuthentication(redirectURI, RedirectURIWithoutLastSlash);
 
        UnityWebRequest request = new UnityWebRequest();
        request.url = $"https://tokenEndpoint.../protocol/openid-connect/token";
 
        request.method = UnityWebRequest.kHttpVerbPOST;
        request.downloadHandler = new DownloadHandlerBuffer();
       
 
 
        request.SetRequestHeader("Content-Type", "application/x-www-form-urlencoded");
 
        string postData = "";
 
        Dictionary<string, string> postParameters = new Dictionary<string, string>() /
            {
                {"grant_type", "authorization_code"},
                {"code", code},
                {"client_id", "myID"},
                {"client_secret", "mySECRET"},
                {"redirect_uri", RedirectURIWithoutLastSlash }
            };
 
        foreach (string key in postParameters.Keys)
            postData += UnityWebRequest.EscapeURL(key) + "=" + UnityWebRequest.EscapeURL(postParameters[key]) + "&";
 
        byte[] data = Encoding.ASCII.GetBytes(postData);
 
        request.uploadHandler = new UploadHandlerRaw(data) ;
 
        request.timeout = 60;
 
        request.SendWebRequest();
 
        while (!request.isDone)
        {
            Debug.Log(request.downloadProgress);
        }
 
        Debug.Log("text by server is: " + request.downloadHandler.text);
 
        TokenClass token = JsonUtility.FromJson<TokenClass>(request.downloadHandler.text);
 
        access_token = token.access_token;
 
        tokenInfo = token;
        Debug.Log("access token is: " + access_token);
 
        return access_token;
    }
 
    private static async Task<string> GetCodeForAuthentication(string redirectURI, string RedirectURIWithoutLastSlash)
    {
 
     
 
        string code = null;
 
        HttpListener http = new HttpListener();
        http.Prefixes.Add(redirectURI);
        http.Start();
 
 
 
        string authorizationRequest = $"https://authCode Endpoint.../protocol/openid-connect/auth?client_id=myID&response_type=code&response_mode=query&scope=profile&redirect_uri={RedirectURIWithoutLastSlash}";
 
        // Opens request in the browser.
        Process web_Login_Process = new Process();
        web_Login_Process.StartInfo.FileName = GetSystemDefaultBrowser();
        web_Login_Process.StartInfo.Arguments = authorizationRequest;
        web_Login_Process.Start();
 
 
            try
            {
             
                var context = await http.GetContextAsync();
                var response = context.Response;
 
                var html = "<html><head><meta http-equiv='refresh' content='10;url=https://localhost'></head><body>Please return to the Digital Twin.</body></html>";
 
 
                string responseString = string.Format(html);
                var buffer = System.Text.Encoding.UTF8.GetBytes(responseString);
                response.ContentLength64 = buffer.Length;
                var responseOutput = response.OutputStream;
                Task responseTask = responseOutput.WriteAsync(buffer, 0, buffer.Length).ContinueWith((task) =>
                {
                    responseOutput.Close();
                    http.Stop();
                    Console.WriteLine("HTTP server stopped.");
                });
           
           
            // Checks for errors.
            if (context.Request.QueryString.Get("error") != null)
                {
                    string debug = context.Request.QueryString.Get("error");
 
                }
                if (context.Request.QueryString.Get("code") == null
                    || context.Request.QueryString.Get("state") == null)
                {
 
                    var debug = context.Request.QueryString; //no keys, Lenght is equal to 0
 
                    var debug3 = context.Request.RawUrl; // favicon.ico is the result
 
 
                }
                // extracts the code
                code = context.Request.QueryString.Get("code");
 
                string tryCode = context.Request.QueryString["code"];
 
                Debug.Log("code is: " + code);
 
               
 
            }
            catch (Exception ex)
            {
                string g = ex.Message;
            }
 
        return code;
    }

any help on this would be really appreciated.对此的任何帮助将不胜感激。

There is a C# Sample that you can follow for the desktop flow and borrow some ideas from.有一个C# 示例,您可以遵循桌面流程并从中借鉴一些想法。 Note that the OAuth flow for console apps is the same as for desktop apps.请注意,控制台应用程序的 OAuth 流程与桌面应用程序相同。

You should be using PKCE for the desktop app security and the above library will implement this for you您应该将 PKCE 用于桌面应用程序安全性,上面的库将为您实现这一点

For something to compare against with the correct OAuth behaviour, see these resources of mine:要与正确的 OAuth 行为进行比较,请参阅我的这些资源:

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 C# 扩展适用于控制台应用程序,但不适用于 MVC Web 应用程序。 我错过了什么吗? - C# Extensions working in console application but not in MVC web application. Am I missing something? 我正在尝试使用C#创建一个基本的损坏计算器,但某些功能无法正常运行 - I am trying to create a basic damage calculator in C#, but something is not working properly 需要了解C#片段,我是否缺少明显的东西? - Need to understand C# piece, am I missing something obvious? c#日期组件错误或我错过了什么? - c# Date component bug or am i missing something? C#IReadOnlyList <t> 防护立即被垂头丧气所破坏,还是我错过了一些东西? - C# IReadOnlyList<t> protection instantlly subverted by downcast, or am I missing something? 有没有一种特殊的方法可以在 c# 的类中使用 Random.Next 或者我只是缺少一些基本的东西? - Is there a special way to use Random.Next inside a class in c# or am i just missing something basic? C# 的 PluralizationService 中是否存在错误,或者我没有正确设置某些内容? - Is there a bug in C#'s PluralizationService, or am I not setting something up properly? 表现怪异的transform.lookat或我错过了一些东西(unity3d C#) - transform.lookat behaving weirdly OR I am missing something (unity3d c#) FromCurrentSynchronizationContext,我缺少什么吗? - FromCurrentSynchronizationContext, am I missing something? 我缺少什么统一/C#? - What am i missing unity/c#?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM