【问题标题】:WebApi + Authenication. How to do it?Web API + 身份验证。怎么做?
【发布时间】:2016-12-04 17:23:53
【问题描述】:

自从我制作自己的项目以来已经有几年了,我正在努力探索更新的做事方式。

现在我想有一个内置 reactjs 的网站,它将 asp.net web api 作为后端。

这将允许我在未来制作移动应用程序以及我想要的任何东西,因为一切都将通过我的 web api 进行。

让我感到困惑的一件事是身份验证以及它实际发生的位置。

我的应用程序的哪一部分正在执行身份验证?是 Web Api 还是网站,还是两者兼而有之?

我的网站将只支持 ouath(google、facebook、Microsoft 等)并且没有传统的登录屏幕。

用户会通过他们的提供商(比如谷歌)来到我的网页注册,然后被允许限制页面并开始做他们想做的任何事情(例如添加课程)。

当他们点击“创建”时,它会向我的 api 发出请求,在我的数据库中查找用户并查看他们是否有权创建新课程。如果是这样,让他们创建并保存它。如果不拒绝。

如果他们没有登录并尝试使用说 postman 访问 web api,他们应该被拒绝。

我知道他们是 Web api 的 OWIN,但我不知道我是否需要它,然后我的 react 网站需要像 OWIN 这样的东西。

我也不想使用 OWIN 内置的数据库表,因为它似乎添加了比我想要的更多的功能(我只想授权用户)。

你可能会说我有点困惑。希望有人能帮助我理解这一切。

【问题讨论】:

    标签: asp.net authentication asp.net-web-api owin


    【解决方案1】:

    这是一个完整的教程,可以帮助您更好地了解 Web 应用程序如何与 .NET 中的 REST api 交互

    https://azure.microsoft.com/en-us/documentation/articles/active-directory-devquickstarts-webapi-dotnet/

    现在您提到您希望使用 Google、FB、MSFT 等作为身份提供者,因此我建议您查看 Microsoft 刚刚推出的以下新产品。它将多个 IDP(身份提供者)集成到您的应用程序中变得非常简单。它还包含完整的代码示例,可帮助您入门。

    aka.ms/aadb2c

    仅出于一般学习目的,我强烈建议您查看此链接,该链接解释了有关令牌、OpenID Connect 以及访问令牌内部内容的一些理论和基础知识。

    http://connect2id.com/learn/openid-connect

    【讨论】:

    • 是的,你会在 Azure 上托管这些东西。幸运的是,最初所有这些身份信息都是免费使用的,所以这是一个尝试的好方法。不过,最后一个链接适用于所有内容。
    【解决方案2】:

    这有点复杂,所以我将解释你必须做什么。

    1) 首先是使用 OAuth 提供程序。微软正在改进 Identity Server。

    身份服务器根据 openid 为您提供授权和身份验证。

    2) 身份服务器必须在另一个项目中编译,并将在数据库中创建 18 个表来控制用户和您的客户端。

    客户端是具有访问权限的应用,例如 Android 应用、Angular 应用或资源服务器。根据您的应用程序,您必须选择工作流程。在身份服务器中,您可以选择其中的 5 个

    https://github.com/IdentityServer

    身份服务器 3 用于 asp.net mvc 4.5+,身份服务器 4 用于 ASP.NET Core 1

    我猜你的服务器将是一个资源服务器,所以如果你要保存用户帐户,你必须做 2 次注册,在身份服务器中注册,然后在你的资源服务器中。

    要配置您的资源服务器并了解两者之间的通信,您必须使用以下内容配置您的 StartUp.cs:

     public class Startup
        {
            public void Configuration(IAppBuilder app)
            {
                // Any connection or hub wire up and configuration should go here
                var clientId = (string)ConfigurationManager.AppSettings["oauth2.clientid"];
                var authority = (string)ConfigurationManager.AppSettings["oauth2.authority"];
    
                app.UseIdentityServerBearerTokenAuthentication(new IdentityServerBearerTokenAuthenticationOptions
                {
                    Authority = authority,
                    ValidationMode = ValidationMode.ValidationEndpoint,
                    RequiredScopes = new[] { clientId },
                });
    
                app.UseResourceAuthorization(new AuthorizationManager());
    
            }
    
    
            private void ConfigureOAuth()
            {
                var formatters = GlobalConfiguration.Configuration.Formatters;
                var jsonFormatter = formatters.JsonFormatter;
                var settings = jsonFormatter.SerializerSettings;
                settings.Formatting = Formatting.Indented;
            }
        }
    

    当您提供令牌并通过 REST 调用服务时,您将在您的 http 标头中发送下一件事:

    header.add("Authorization", "TypeToken Token");

    使用最多的类型令牌是 Bearer

    当您使用 C# 中的 identity.client 类登录时,身份服务器会提供此令牌,为您提供了一个很棒的工具来完成最困难的部分。

    配置客户端:

      private TokenClient GetTokenClient()
            {
                var clientId = (string)ConfigurationManager.AppSettings["oauth2.clientid"];
                var clientSecret = (string)ConfigurationManager.AppSettings["oauth2.client-secret"];
                var tokenEndPoint = (string)ConfigurationManager.AppSettings["openid.endpoints.token"];
    
                var client = new TokenClient(
                    tokenEndPoint,
                    clientId,
                   clientSecret
                );
    
                return client;
            }
    

    获取令牌:

    Route("LoginOAUth")]
            [HttpPost]
            public async Task<TokenResponse> LoginOAUth(LoginViewModel credentials)
            {
                var result = await GetTokenClient().RequestResourceOwnerPasswordAsync(credentials.Correo, credentials.Password,
                                "offline_access AppNameExample-IdentityClient-morgan");
    
                return result;
            }
    
      public class LoginModel
        {
            public string Email { get; set; }
            public string Password { get; set; }
        }
    

    此令牌必须由客户端存储,并且每次您调用端点时,您的资源服务器都会对身份服务器进行内部调用,以检查您的令牌是否有效,以及您的令牌是否有效过期与否。

    在令牌中,您获得 2 种信息范围和声明,这些范围和声明向您说明“资源的权利”和用户数据信息,如 id、电子邮件、姓名等。在这里阅读这些属性是自定义 AuthorizationAttribute 示例:

      public class AuthorizationManager : ResourceAuthorizationManager
        {
    
            public override Task<bool> CheckAccessAsync(ResourceAuthorizationContext context)
            {
    
                switch (context.Resource.First().Value)
                {
                    case "claims":
                        return AuthorizeValues(context);
                    default:
                        return Nok();
                }
            }
    
            Task<bool> AuthorizeValues(ResourceAuthorizationContext context)
            {
                switch (context.Action.First().Value)
                {
                    case "read":
                        return Eval(context.Principal.HasClaim("role", "api-read"));
                    default:
                        return Nok();
                }
            }
    
        }
    

    真的很复杂,我花了 1 个月的时间研究 OAuth 2.0 协议以及身份服务器的工作原理。祝你好运

    【讨论】:

    • 还是有点糊涂。所以我需要做 2 次身份验证?一个允许他们使用我的webapi,一个允许他们登录我的api?我还需要生成你所说的那 18 个表吗?我试图避免这样的开销。
    • 对不起,这是不可能的。您只需要 1 个身份验证,Oauth 2.0。身份服务器为您提供所有库、nugets 等来做到这一点。一步一步阅读本教程:这家伙详细解释了一切:scottbrady91.com/Identity-Server/…
    • Sigh oauth 的东西在几年前刚开始时似乎更简单。我不需要 18 个表来执行此操作(更多的表然后我的整个应用程序将需要运行我的网站),我只需要 db 中的 1 个字段。
    • 如果您想要自己的 OAuth,则需要这样做,否则如果您想使用其他 OAuth 提供商,如 Google、FB、Microsoft 等。是的,数据库中只需要多一个字段.仅当您要构建自己的 OAuth 提供程序时才使用 Identity Server。顺便说一句,这 18 个表是使用 nuget 控制台中的 db-migration 命令创建的。
    猜你喜欢
    • 1970-01-01
    • 2017-10-22
    • 2014-01-28
    • 2012-06-16
    • 2016-07-03
    • 1970-01-01
    • 1970-01-01
    • 2012-10-08
    • 2016-11-13
    相关资源
    最近更新 更多