如何在成为旧版ASP.NET MVC应用程序的一部分时对Web API 2中的用户进行身份验证?

时间:2015-06-28 22:04:30

标签: c# asp.net-mvc authentication asp.net-web-api asp.net-web-api2

我有一个Web API,目前AngularJS应用程序在ASP.NET MVC Web应用程序中使用。 MVC应用程序使用ASP.NET Forms Authentication作为身份验证机制。 当客户端不是Web客户端时,我应该如何验证Web API的用户,例如一个独立的服务。我现在所做的是为Web API添加一个登录方法,为任何人提供正确的凭据访问权限:

 <li><a href="<?php echo URL; ?>index"><span class="glyphicon glyphicon-home"></span>  Home</a></li>

        <li><a href="<?php echo URL; ?>voitures-et-automobiles/liste/"><span class="glyphicon icon-car"></span> Voitures</a></li>
        <li><a href="<?php echo URL; ?>a/b/"><span class="glyphicon glyphicon-cog"></span> Pieces Auto</a></li>

        <li><a href="<?php echo URL; ?>test/test1/test2/"><span class="glyphicon glyphicon-dashboard"></span> classes</a></li>
        <li><a href="<?php echo URL; ?>q/c/"><span class="glyphicon glyphicon-road"></span> test4</a></li>
        <li><a href="<?php echo URL; ?>magazine/"><span class="glyphicon glyphicon-book"></span> blog</a></li>

我的问题是,如果这应该如何解决,或者是否有更好的方法?

1 个答案:

答案 0 :(得分:3)

您可以使用WebApi2的令牌认证机制。

流程将是这样的:

用户在以下网址向您发送https请求:

https://yourApiUrl/Token

请求的内容类型应为:

application/x-www-form-urlencoded

正文应包括:

grant_type=password&username=yourWebsFormsUsername&password=yourWebFormsPassword

你的OWIN启动课会看起来像这样:

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

    public static string PublicClientId { get; private set; }

    public void ConfigureAuth(IAppBuilder app)
    {
        app.UseCookieAuthentication(new CookieAuthenticationOptions());
        app.UseExternalSignInCookie(DefaultAuthenticationTypes.ExternalCookie);
        app.UseCors(Microsoft.Owin.Cors.CorsOptions.AllowAll);

        PublicClientId = "self";
        OAuthOptions = new OAuthAuthorizationServerOptions
        {
            TokenEndpointPath = new PathString("/Token"),
            Provider = new YourOAuthProvider(),
            AuthorizeEndpointPath = new PathString("/api/Account/ExternalLogin"),
            AccessTokenExpireTimeSpan = TimeSpan.FromDays(14),
            AllowInsecureHttp = true,
        };

        app.UseOAuthBearerTokens(OAuthOptions);
    }
}

注意上面的YourOAuthProvider,这是重要的部分。这是您的自定义提供程序,它将根据您拥有的凭据存储来验证您的用户名/密码。在你的情况下aspnet_membership表。此验证在下面的方法RequestHasValidCredentials:

中完成
public class YourOAuthProvider : OAuthAuthorizationServerProvider
{
    public string apikey = string.Empty;

    public override async Task ValidateClientAuthentication(OAuthValidateClientAuthenticationContext context)
    {
        context.Validated();
    }

    public override async Task GrantResourceOwnerCredentials(OAuthGrantResourceOwnerCredentialsContext context)
    {

        if (RequestHasValidCredentials(context.UserName, context.Password))
        {
            var id = new ClaimsIdentity(context.Options.AuthenticationType);
            id.AddClaim(new Claim("username", context.UserName));

            context.Validated(id);
        }
        else
        {
            context.SetError("invalid_grant", "The user name or password is incorrect.");
            return;
        }            
    }
}

您的用户将获得的响应将是一个令牌,其中将包含用户名或您在上述方法中添加到上下文中的任何其他信息:

id.AddClaim(new Claim("username", context.UserName));

来自上述令牌api调用的响应将是这样的:

{
    "access_token": "9TIpW2m2rUbB_Bmb7kKAQ9GH4hgfnKF8g3fL0tAre2gcFjI45fajmG6qdOJe-A",
    "token_type": "bearer",
    "expires_in": 1209599
}

然后,您的用户必须将此令牌作为所有API调用的Http Authorization标头传递。他们需要使用承载方案来传递它,例如:

Bearer 9TIpW2m2rUbB_Bmb7kKAQ9GH4hgfnKF8g3fL0tAre2gcFjI45fajmG6qdOJe-A

由于此令牌包含用户名,您将能够知道该用户是谁。现在最后要读取此令牌并检索用户名。为此,您需要创建一个自定义的Authorize属性,并用它来装饰您的控制器或方法。

public class YourAuthorizeAttribute : AuthorizationFilterAttribute
{
    public override void OnAuthorization(HttpActionContext actionContext)
    {
        var ticket = Startup.OAuthOptions.AccessTokenFormat.Unprotect(actionContext.Request.Headers.Authorization.Parameter);

        string username = claims.Where(x => x.Type == "username").FirstOrDefault();

        base.OnAuthorization(actionContext);
    }
}

一旦您拥有用户名,就可以在此处添加所有其他自定义授权逻辑。

您可以在生成令牌时传递其他自定义信息,并在此处阅读。 (如果您需要任何其他特殊授权逻辑。)

其冗长的方法,但将会有任何凭据存储。