【问题标题】:How to get client id and a client secret from MVC5 in OAuth2?如何在 OAuth2 中从 MVC5 获取客户端 ID 和客户端密码?
【发布时间】:2017-08-07 12:15:30
【问题描述】:

我正在我的 MVC 5 应用程序中实现 OAuth2 身份验证,因此我可以在我的 Android 应用程序中使用它。但我不确定这一切是如何进行的,因为我以前从未使用过 Oauth2 或任何令牌身份验证。

到目前为止,我在 MVC 中实现了以下代码:

OwinContextExtensions.cs

public static class OwinContextExtensions
{
    public static string GetUserId(this IOwinContext ctx)
    {
        var result = "-1";
        var claim = ctx.Authentication.User.Claims.FirstOrDefault(c => c.Type == "UserID");
        if (claim != null)
        {
            result = claim.Value;
        }
        return result;
    }
}

Startup.Auth.cs

public partial class Startup
{
    public static OAuthAuthorizationServerOptions OAuthOptions { get; private set; }

    static Startup()
    {
        OAuthOptions = new OAuthAuthorizationServerOptions
        {
            TokenEndpointPath = new PathString("/token"),
            Provider = new OAuthAppProvider(),
            AccessTokenExpireTimeSpan = TimeSpan.FromDays(2),
            AllowInsecureHttp = true
        };
    }

    public void ConfigureAuth(IAppBuilder app)
    {
        app.UseOAuthBearerTokens(OAuthOptions);
    }
}

OAuthAppProvider.cs

public class OAuthAppProvider : OAuthAuthorizationServerProvider
{
    private ProtokolEntities db = new ProtokolEntities();
    public IFormsAuthenticationService FormsService { get; set; }
    public IMembershipService MembershipService { get; set; }


    public override Task GrantResourceOwnerCredentials(OAuthGrantResourceOwnerCredentialsContext context)
    {
        if (MembershipService == null) { MembershipService = new AccountMembershipService(); }

        return Task.Factory.StartNew(() =>
        {
            var username = context.UserName;
            var password = context.Password;


            var userID = db.aspnet_Users.Where(x => x.UserName == username).SingleOrDefault().UserId.ToString();

            if (MembershipService.ValidateUser(username, password))
            {
                var claims = new List<Claim>()
                {
                    new Claim(ClaimTypes.Name, username),
                    new Claim("UserID", userID)
                };

                ClaimsIdentity oAutIdentity = new ClaimsIdentity(claims, Startup.OAuthOptions.AuthenticationType);
                context.Validated(new AuthenticationTicket(oAutIdentity, new AuthenticationProperties() { }));
            }
            else
            {
                context.SetError("invalid_grant", "Error");
            }
        });
    }

    public override Task ValidateClientAuthentication(OAuthValidateClientAuthenticationContext context)
    {
        if (context.ClientId == null)
        {
            context.Validated();
        }
        return Task.FromResult<object>(null);
    }
}

Startup.cs.cs

[assembly: OwinStartup(typeof(PageOffice.Startup))]
namespace PageOffice
{

    public partial class Startup
    {
        public void Configuration(IAppBuilder app)
        {
            app.MapSignalR();

            ConfigureAuth(app);
        }
    }
}

当我打开 Postman 并在 http://localhost:1076/token 上使用 POST 方法时,我打开 Body -> raw 并写入

grant_type=password&password=mypassword&username=myusername

之后我得到了这个结果:

{
    "access_token": "QmmWSh4OZPfC8uv-jyzFzZx1KP05T8b09QlPP3Cy-_Zr9qvWtzWpxNTXOhc4U387N6VHNCnIPklgTEk8CISMyXlcsWAz7MxlRN8qI_Ajg8gjEphHUS1SrO0uDRG2XRqtX1gvTVupym_1xtsdjlwj2VXoc6ySvR0ihb2YjuXnSd4CNgKKaMBQLb1w8P1XB13jc4Pc5tump4-Y4dYn3A5hpvtc9fqpgVAUjZFdiJ_HXMiIpgmqdIFim0Ty8oRZolzpm3RSMPRV6ZIpZBqHG1A2kcdWN-52ZkHuL4_7U743vW0",
    "token_type": "bearer",
    "expires_in": 172799
}

如何找到“client id”和“client secret”参数? 另外我不太明白如何在android中使用这个access_token,this教程上的解释就足够了吗?

感谢阅读,抱歉这么多代码:)

【问题讨论】:

    标签: android asp.net-mvc oauth oauth-2.0


    【解决方案1】:

    有一个关于 OAuth2 for native applications 的 RFC。它建议使用授权代码授予流程,但没有客户端密码,因为您无法将密码安全地保存在应用程序二进制文件中。

    您现在使用的资源所有者密码凭证流程(请参阅OAuth2 RFC)仅应在资源所有者可以完全信任应用程序的极少数情况下使用,因为应用程序必须知道他们的密码。

    当您在 OAuth2 提供商处注册您的应用程序(客户端)时,您会获取或指定客户端 ID 和密码。

    您链接的教程似乎讨论的是 OAuth 版本 1,而不是 2。

    【讨论】:

    • 谢谢,我现在走对了。我发送了一个错误的链接,现在它已修复。我认为本教程会有所帮助。
    • @Jan Halasa,正如您提到的客户端是,并且可以在应用程序注册期间获得秘密。假设我的客户端是移动设备,那么我需要在我的代码中硬核客户端 ID 和秘密吗?还是需要存储在 SQL 中并与硬编码的值进行比较?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2018-06-05
    • 2016-02-13
    • 2017-11-16
    • 1970-01-01
    • 2015-11-09
    • 2017-10-18
    • 1970-01-01
    相关资源
    最近更新 更多