Use a different auth method for external api calls

I have a Web API application with MVC. When a user uses a website, authentication and authorization are now automatically handled by the global form authentication that I use, configured in Web.config as follows:

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

This ensures that only registered users can access the site and call the API.

But I also have an external Windows client for which I would like to use a different authentication method. In a test without auth forms, I set up a custom attribute, AuthorizeAttribute, which I can use in my controllers, for example:

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

An authorized attribute looks something like this:

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 auth (- this), , - .

+4
2

FormAuthentication . FormAuthentication.

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")
            });
        }
    }
}
+1

- . ( ). , , , , .

, , , :

  • ,
  • , ,
  • ,

. /hh: mm: ss: ms/full/path/enpoint/enpoint. , , 30 .

. , Ticket, . , , , http authorization header.

public ActionResult GetAuthententicationToken(Credentials credentials)
{
   //Authenticate the user
   //Insert a record into the Ticket database table and return hash key as token.
   //Return the token to the client.
}

, , , .

HTTP- , get GetAuthententicationToken().

AuthorizeAttribute, , GetAuthententicationToken.

public class ApiAuthAttribute : AuthorizeAttribute {
    public override void OnAuthorization(HttpActionContext context) {
        //Get authorization token from header
        //if caching then get associated Ticket from cache else lookup in database
        //if not valid throw security exception
        //Apply principal to current user based on lookup above       
    }
}

, FormsAuthentication ?

Forms Authentication , MVC, , .

, , - .

 public FormsAthentication.CreateAuthenticationTicket()
    {
        //Authenticate user
        //Insert a record into the Ticket database table and return hash key as token.
        //Add that token to ticket data
    }

, . Application_AuthenticateRequest Global.asax.

protected void Application_AuthenticateRequest(Object sender, EventArgs e)
{
    //if FormsAuthentication.IsAuthenticated
    //Get the token saved in the ticket data   
    //Save the token value in the http authorization header 
}

. Ticket . , , , , .

+1

Source: https://habr.com/ru/post/1652701/


All Articles