I have some problems accepting the Web API 2 Identity. In project.
Add StartUp.cs
Like this:
using Microsoft.Owin; using Owin; [assembly: OwinStartup(typeof(MyNamespace.Startup))] namespace MyNamespace { public partial class Startup { public void Configuration(IAppBuilder app) { ConfigureAuth(app); } } }
After that, I add an incomplete class to enable Token authorization:
namespace MyNamespace { 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); PublicClientId = "self"; OAuthOptions = new OAuthAuthorizationServerOptions { TokenEndpointPath = new PathString("/Token"), Provider = new ApplicationOAuthProvider(PublicClientId), AuthorizeEndpointPath = new PathString("/api/Account/ExternalLogin"), AccessTokenExpireTimeSpan = TimeSpan.FromDays(14) }; app.UseOAuthBearerTokens(OAuthOptions); } } }
I also implement custom functionality (e.g. UserStore, UserManager).
I take the "ExternalLogin" method from the example and change.
// GET api/Account/ExternalLogin [OverrideAuthentication] [HostAuthentication(DefaultAuthenticationTypes.ExternalCookie)] [AllowAnonymous] [Route("ExternalLogin", Name = "ExternalLogin")] public async Task<IHttpActionResult> GetExternalLogin(string provider, string error = null) { if (error != null) { return Redirect(Url.Content("~/") + "#error=" + Uri.EscapeDataString(error)); } if (!User.Identity.IsAuthenticated) { return new ChallengeResult(provider, this); } ExternalLoginData externalLogin = ExternalLoginData.FromIdentity(User.Identity as ClaimsIdentity); if (externalLogin == null) { return InternalServerError(); } if (externalLogin.LoginProvider != provider) { Authentication.SignOut(DefaultAuthenticationTypes.ExternalCookie); return new ChallengeResult(provider, this); } User user = await UserManager.FindAsync(new UserLoginInfo(externalLogin.LoginProvider, externalLogin.ProviderKey)); bool hasRegistered = user != null; if (hasRegistered) { Authentication.SignOut(DefaultAuthenticationTypes.ExternalCookie); ClaimsIdentity oAuthIdentity = await UserManager.CreateIdentityAsync(user, OAuthDefaults.AuthenticationType); ClaimsIdentity cookieIdentity = await UserManager.CreateIdentityAsync(user, CookieAuthenticationDefaults.AuthenticationType); AuthenticationProperties properties = ApplicationOAuthProvider.CreateProperties(user.UserName); Authentication.SignIn(properties, oAuthIdentity, cookieIdentity); } else { IEnumerable<Claim> claims = externalLogin.GetClaims(); ClaimsIdentity identity = new ClaimsIdentity(claims, OAuthDefaults.AuthenticationType); Authentication.SignIn(identity); } return Ok(); }
After that, I launched the application and tried to enter the application as follows:
var loginData = { grant_type: 'password', username: "test", password: "test" }; $.ajax({ type: 'POST', url: '/Token', data: loginData }).done(function (data) { alert(data.username); sessionStorage.setItem(tokenKey, data.access_token); }).fail(function (data) { alert(data); });
I have a 404 error. I'm trying to send a user request to / Token via fiddler, and this will produce the same result. Then I check that the api / Account / ExternalLogin action is available, this status code is 401 response. I am checking the Owin links, Microsoft.Owin is correct. What is the problem? Where is my problem?
UPD:
public class ApplicationOAuthProvider : OAuthAuthorizationServerProvider { private readonly string _publicClientId; [Dependency] public ICustomUserManager UserManager { get;set; } public ApplicationOAuthProvider(string publicClientId) { if (publicClientId == null) { throw new ArgumentNullException("publicClientId"); } _publicClientId = publicClientId; } public override async Task GrantResourceOwnerCredentials(OAuthGrantResourceOwnerCredentialsContext context) { var userManager = context.OwinContext.GetUserManager<ICustomUserManager>(); User user = await userManager.FindAsync(context.UserName, context.Password); if (user == null) { context.SetError("invalid_grant", "The user name or password is incorrect."); return; } ClaimsIdentity oAuthIdentity = await UserManager.CreateIdentityAsync(user, OAuthDefaults.AuthenticationType); ClaimsIdentity cookieIdentity = await UserManager.CreateIdentityAsync(user, CookieAuthenticationDefaults.AuthenticationType); AuthenticationProperties properties = CreateProperties(user.UserName); AuthenticationTicket ticket = new AuthenticationTicket(oAuthIdentity, properties); var val = context.Validated(ticket); context.Request.Context.Authentication.SignIn(cookieIdentity); } public override Task TokenEndpoint(OAuthTokenEndpointContext context) { foreach (KeyValuePair<string, string> property in context.Properties.Dictionary) { context.AdditionalResponseParameters.Add(property.Key, property.Value); } return Task.FromResult<object>(null); } public override Task ValidateClientAuthentication(OAuthValidateClientAuthenticationContext context) {