asp.net – 使用另一个auth方法进行外部api调用

我有一个带有MVC的Web API应用程序.当用户使用该网站时,身份验证和授权当前由我使用的全局表单身份验证自动处理,在Web.config中配置如下:

<authentication mode="Forms">
  <forms loginUrl="~/Login" slidingExpiration="true" timeout="1800" defaultUrl="/"></forms>
</authentication>
<authorization>
  <deny users="?" />
</authorization>

这样可确保只有登录的用户才能访问该站点并调用API.

但我也有一个外部Windows客户端,我想使用另一种身份验证方法.在没有表单身份验证的测试中,我设置了一个自定义AuthorizeAttribute,我可以在我的控制器中使用,如下所示:

[ApiAuth]
public IEnumerable<string> Get() {
    // Return the resource
}

AuthorizeAttribute看起来像这样:

public class ApiAuthAttribute : AuthorizeAttribute {
    public override void OnAuthorization(HttpActionContext context) {
        // Authenticate the request with a HMAC-based approach
    }
}

这在隔离工作正常,但我无法弄清楚如何允许两种auth方法.我希望ApiAuth作为后备,如果表单auth不起作用(或反过来,无论什么工作),但如果我应用[ApiAuth]属性,只会使用它,普通用户无法访问api.

那么,我如何使用多个auth方法,或者使用其中一个作为后备,如果另一个失败,或者配置服务器,以便Windows客户端可以以其他方式调用API,然后保持相同的MVC应用程序API调用可用于两种类型的客户端?

谢谢.

编辑:我可能采取的一种方法是让Windows客户端使用表单身份验证(类似于this)进行身份验证,但它看起来非常像黑客,我宁愿使用其他方法.

最佳答案 FormAuthentication可以实现多种方式.在过去,我们使用
FormAuthentication Ticket.

现在,您可以使用基于声明的身份验证与Owin Middleware,它基本上是ASP.Net Identity的精简版本.

在ApiAuthAttribute中对用户进行身份验证后,您将创建Principal对象.

Web.config文件

你不应该使用< authorization> ASP.Net MVC中的标记.相反,您想要使用过滤器.

<authentication mode="Forms">
  <forms loginUrl="~/Account/Login" timeout="2880" />
</authentication>

ApiAuthAttribute

public class ApiAuthAttribute : AuthorizeAttribute
{
    public override void OnAuthorization(HttpActionContext context)
    {
        // Authenticate the request with a HMAC-based approach

        // Create FormAuthentication after custom authentication is successful
        if (!HttpContext.Current.User.Identity.IsAuthenticated)
        {
            User user = new User {Id = "1234", UserName = "johndoe", 
                 FirstName = "John", LastName = "Doe"};

            // This should be injected using IoC container. 
            var service = new OwinAuthenticationService(
                 new HttpContextWrapper(HttpContext.Current));
            service.SignIn(user);
        }
    }
}

认证

public class User
{
    public string Id { get; set; }
    public string UserName { get; set; }
    public string FirstName { get; set; }
    public string LastName { get; set; }
}

public interface IAuthenticationService
{
    void SignIn(User user);
    void SignOut();
}

public class OwinAuthenticationService : IAuthenticationService
{
    private readonly HttpContextBase _context;
    private const string AuthenticationType = "ApplicationCookie";

    public OwinAuthenticationService(HttpContextBase context)
    {
        _context = context;
    }

    public void SignIn(User user)
    {
        IList<Claim> claims = new List<Claim>
        {
            new Claim(ClaimTypes.Sid, user.Id),
            new Claim(ClaimTypes.Name, user.UserName),
            new Claim(ClaimTypes.GivenName, user.FirstName),
            new Claim(ClaimTypes.Surname, user.LastName),
        };

        /*foreach (Role role in user.Roles)
        {
            claims.Add(new Claim(ClaimTypes.Role, role.Name));
        }*/

        ClaimsIdentity identity = new ClaimsIdentity(claims, AuthenticationType);

        IOwinContext context = _context.Request.GetOwinContext();
        IAuthenticationManager authenticationManager = context.Authentication;

        authenticationManager.SignIn(identity);
    }

    public void SignOut()
    {
        IOwinContext context = _context.Request.GetOwinContext();
        IAuthenticationManager authenticationManager = context.Authentication;

        authenticationManager.SignOut(AuthenticationType);
    }
}

Startup.cs

[assembly: OwinStartup(typeof(YOUR_APPLICATION.Startup))]
namespace YOUR_APPLICATION
{
    public class Startup
    {
        public void Configuration(IAppBuilder app)
        {
            app.UseCookieAuthentication(new CookieAuthenticationOptions
            {
                AuthenticationType = "ApplicationCookie",
                LoginPath = new PathString("/Account/Login")
            });
        }
    }
}
点赞