C# WPF 应用程序中的 Keycloak:如何在普通 MVVM WPF 应用程序中访问 C# 中给定用户/密码的角色?

Posted

技术标签:

【中文标题】C# WPF 应用程序中的 Keycloak:如何在普通 MVVM WPF 应用程序中访问 C# 中给定用户/密码的角色?【英文标题】:Keycloak in C# WPF Application: How can I access the roles of a given user/password in C# in a normal MVVM WPF application? 【发布时间】:2020-11-12 15:08:54 【问题描述】:

我正在寻找 C# 中 Keycloak 客户端的工作实现。 DylanPlecki 和 MattMorg(后来)在 github 上的两个项目都不适合我,而且很可能不再维护。

我的任务是让给定用户的所有角色在我们的数据库服务器上实现更精细的数据库访问。所以实际上我首先不是作为身份验证服务器的keycloak,而是更多地获取用户的信息。因此,在我们公司,我们正在开始使用 OAUTh2.0 ;-)。

所以这是我的问题:有谁知道,如何最有效地访问 keycloak 服务器以保护应用程序的安全性并获得角色?也许通过 RestAPI 或 OIDC 协议?

【问题讨论】:

【参考方案1】:

@Thomas Brüggemann'sanswer(最终)让我走上了正确的道路:

我使用 RestClient 类来获取我的用户的角色。最后未解决的是我必须将输入的凭据存储在 RAM 中。如果您在 webapp 的上下文中,这肯定会在 keycloak 登录页面实现中得到更好的解决。但我继续寻找更好的解决方案。也许作为第一步,我会在获得令牌后直接删除用户/密码组合。

我的目标是访问 keycloak 服务器以获取我需要改进用户管理的角色。作为一个非常原始的测试示例,我在最后一行得到一个字典,其中包含所请求用户的所有角色:

using RestSharp;
using System.IdentityModel.Tokens;
using Newtonsoft.Json;
using System.Security.Claims;
using System.Web;
using System.Security.Principal;
using Microsoft.AspNet.Identity;
[..]

    
[..]
    public String GetAccessAndRefreshToken()
    
        RestClient client = new RestClient("http://YourKeycloakServer:YourKCPort/auth/realms/YourRealm/protocol/openid-connect/token");

        RestRequest request = new RestRequest(Method.POST);
        request.AddHeader("cache-control", "no-cache");
        request.AddHeader("content-type", "application/x-www-form-urlencoded");
        request.AddParameter("grant_type", "password");
        request.AddParameter("client_id", "YourAppsNameInKeycloak");
        request.AddParameter("username", AuthenticationViewModel.UserName);
        request.AddParameter("password", AuthenticationViewModel.Pass);
        request.AddParameter("client_secret", "YourSecretinKeycloak");
        IRestResponse response = client.Execute(request);
        String content = response.Content;
        return content;
    

    public List<String> GetRoles(String content)
    
        JwtSecurityTokenHandler jwtHandler = new JwtSecurityTokenHandler();
        //string pattern = @"\n.* ""(.*)"",";
        String pattern = @".*access_token\"":\""(.*)\"",\""expires.*";
        MatchCollection accessTokenMatch = Regex.Matches(content, pattern, RegexOptions.IgnoreCase);
        var group1 = (String)accessTokenMatch[0].Groups[1].ToString();
        JwtSecurityToken token = (JwtSecurityToken)jwtHandler.ReadToken((String)accessTokenMatch[0].Groups[1].ToString());

        Claim realmAccessClaim = token.Claims.First((claim) => claim.Type == "realm_access");
        Dictionary<string, string[]> realmAccessAsDict = JsonConvert.DeserializeObject<Dictionary<string, string[]>>(realmAccessClaim.Value);
        List<String> roles = realmAccessAsDict.FirstOrDefault().Value.ToList();
        return roles;
    
[..]

最后你会得到一个字符串形式的角色列表,你可以手动解析它们。

【讨论】:

以上是关于C# WPF 应用程序中的 Keycloak:如何在普通 MVVM WPF 应用程序中访问 C# 中给定用户/密码的角色?的主要内容,如果未能解决你的问题,请参考以下文章

如何从 C# 中的 DatePicker(WPF) 中获取价值?

如何使用 c# WPF 打开 chm 文件中的特定页面

如何在 C# 和 WPF 中的实体框架中创建数据库和表?

C# WPF 工具包:如何​​使数据网格中的单元格可编辑?

禁用 WPF 窗口标题栏中的关闭按钮 (C#)

如何从 C# WPF 中的嵌入字体将字体文件添加到 Stimulsoft 报告