具有Identity Auth的MVC应用程序内的Web API Basic Auth

时间:2015-06-19 07:33:38

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

所以我有C# MVC个应用使用Identity进行身份验证。我现在需要通过Web API向我的一些客户公开一些内容。而不是构建单独的应用程序,项目,部署......我只是在现有项目中添加了API Controller。为了让我的客户保持简单,我决定使用Basic Auth,而是选择强制我的客户使用SSL连接到我的API。

我已经按照这个非常有用的教程在我的API中实现了Basic Authhttp://www.piotrwalat.net/basic-http-authentication-in-asp-net-web-api-using-message-handlers/

问题是,他们的说明会占用整个应用的Auth ...

我需要我的MVC应用继续使用当前使用的Identity Auth并希望滚动我自己的自定义属性(例如[APIAuthorize]),以便它仅适用于我的{{ 1}}。

我可能会破解并试图让它工作,但由于这涉及到安全性,我决定请求一些有关如何最好地实现这一点的帮助。具体来说,我需要知道 1)我在API Controller(如果有的话)中做了什么,因为上面的网址建议我这样做:

Global.asax

但同样,这会将身份验证接管到整个应用... 2)我需要在自定义身份验证属性中执行哪些操作才能使所有这些功能无缝地工作。

当然,如果有更好的方法来完成所有这些(不创建单独的应用程序或增加我的客户的实施难度),那么我全都听见了。

1 个答案:

答案 0 :(得分:4)

我使用过滤器属性来装饰我想要向Simple Auth公开的动作。我不记得我从哪里得到这个代码(可能stackoverflow我只是没有链接所以我不能声称它的信用)

public class BasicHttpAuthorizeAttribute : AuthorizeAttribute
    { 
protected override bool IsAuthorized(HttpActionContext actionContext)
        {
            if (Thread.CurrentPrincipal.Identity.Name.Length == 0)
            { 
                // Get the header value
                AuthenticationHeaderValue auth = actionContext.Request.Headers.Authorization;
                // ensure its schema is correct
                if (auth != null && string.Compare(auth.Scheme, "Basic", StringComparison.OrdinalIgnoreCase) == 0)
                {
                    // get the credientials
                    string credentials = UTF8Encoding.UTF8.GetString(Convert.FromBase64String(auth.Parameter));
                    int separatorIndex = credentials.IndexOf(':');
                    if (separatorIndex >= 0)
                    {
                        // get user and password
                        string passedUserName = credentials.Substring(0, separatorIndex);
                        string passedPassword = credentials.Substring(separatorIndex + 1);
                        SimpleAES crypto = new SimpleAES();
                        string userName = crypto.DecryptString(ConfigurationManager.AppSettings.Get(Constants.SIMPLEUSERNAME));
                        string password = crypto.DecryptString(ConfigurationManager.AppSettings.Get(Constants.SIMPLEUSERPASSWORD));

                        // validate
                        if (passedUserName == userName && passedPassword == password)
                        {
                            Thread.CurrentPrincipal = actionContext.ControllerContext.RequestContext.Principal = new GenericPrincipal(new GenericIdentity(userName, "Basic"), new string[] { });
                        }
                    }
                }
            }
            return base.IsAuthorized(actionContext);
        }
    }

然后我就这样使用

[BasicHttpAuthorize]
public HttpResponseMessage MyExposedSimpleAuthAction()