Asp.Net WebApi OWIN身份验证
遵循一个在线教程以使用OWIN使用基于令牌的身份验证后,我设法让我的测试应用程序根据硬编码的用户名/密码进行身份验证,如演示所做的那样。Asp.Net WebApi OWIN身份验证
但是,现在我想从我的web应用程序中使用我的模型。
正如演示所说,我的身份验证是在这段代码中进行的。
namespace UI
{
public class AuthorisationServerProvider : OAuthAuthorizationServerProvider
{
public override async Task ValidateClientAuthentication(OAuthValidateClientAuthenticationContext context)
{
context.Validated(); // Means I have validated the client.
}
public override async Task GrantResourceOwnerCredentials(OAuthGrantResourceOwnerCredentialsContext context)
{
// Here we validate the user...
var identity = new ClaimsIdentity(context.Options.AuthenticationType);
if (context.UserName == "user" && context.Password == "password")
{
identity.AddClaim(new Claim(ClaimTypes.Role, "admin"));
identity.AddClaim(new Claim("username", "user"));
identity.AddClaim(new Claim(ClaimTypes.Name, "My Full Name"));
context.Validated(identity);
}
else
{
context.SetError("Invalid grant", "Username or password are incorrect");
return;
}
}
}
}
我有一个WebAPI控制器,我从我的webapi控制器接收模型,并...不知道如何调用上面的代码。目前,上面的代码需要调用myurl/token - 这是在启动代码中定义的。
public class Startup
{
public void Configuration(IAppBuilder app)
{
// Enables cors origin requests.
app.UseCors(Microsoft.Owin.Cors.CorsOptions.AllowAll);
// Config OAuth authorisation server;
var myProvider = new AuthorisationServerProvider();
OAuthAuthorizationServerOptions options = new OAuthAuthorizationServerOptions
{
AllowInsecureHttp = true, // Live version should use HTTPS...
TokenEndpointPath = new PathString("/token"),
AccessTokenExpireTimeSpan = TimeSpan.FromDays(1),
Provider = myProvider
};
app.UseOAuthAuthorizationServer(options);
app.UseOAuthBearerAuthentication(new OAuthBearerAuthenticationOptions());
HttpConfiguration config = new HttpConfiguration();
WebApiConfig.Register(config);
}
}
所以,我猜我的webapi调用的url应该是/ token?所以,在我的UI我的(剔除视图模型)的代码,我尝试这样做:
Login()
{
var data = {
username : this.login.emailAddress(),
password : this.login.password(),
RememberMe: this.login.rememberMe(),
grant_type: "password"
}
return $.ajax({
type: "POST",
data: data ? JSON.stringify(data) : null,
dataType: "json",
url: "/token",
contentType: "application/json"
}).done((reply) => {
alert("Done!");
});
}
但是,我得到一个异常:
“error”: “unsupported_grant_type”
在“邮差”,我能够认证硬编码的用户名/密码。
但我不知道如何从我的UI线了我的API调用,进行身份验证。
我希望我的API控制器(ASP.Net的WebAPI)上创建一个“登录”方法,就像这样:
[Route("login"), HttpPost, AllowAnonymous]
public ReplyDto Login(LoginRequest login)
{
ReplyDto reply = _userService.Login(login.Email, login.Password);
return reply;
}
所以,我_userService检查用户是否在数据库中...如果是这样,请在这里调用我的OAuth身份验证传递几个参数。但不知道这是可能的。我可以从这个API方法调用我的身份验证吗?我需要删除/令牌位。
你不需要创建一个Login方法,因为你已经拥有了它。这是http://localhost:1234/token。如果用户存在并且密码正确,这将生成一个令牌。但得到这个行为,你需要从OAuthAuthorizationServerProvider
public class DOAuthServerProvider : OAuthAuthorizationServerProvider
派生来实现自己的AuthServerProvider,然后你会覆盖的方法来实现你的逻辑:
public override async Task GrantResourceOwnerCredentials(OAuthGrantResourceOwnerCredentialsContext context)
{
try
{
string allowedOrigin = context.OwinContext.Get<string>(DOAuthStatic.ALLOWED_CORS_ORIGINS_KEY);
if (allowedOrigin != null)
{
context.OwinContext.Response.Headers[DOAuthStatic.CORS_HEADER] = allowedOrigin;
}
DAuthenticationResponse authResponse = await _authRepository.Authenticate(context.UserName, context.Password);
if (!authResponse.IsAuthenticated)
{
context.SetError(OAuthError.InvalidGrant, $"{(int)authResponse.AuthenticateResult}:{authResponse.AuthenticateResult}");
return;
}
if (authResponse.User.ChangePasswordOnLogin)
{
_userAuthenticationProvider.GeneratePasswordResetToken(authResponse.User);
}
IDictionary<string, string> props = new Dictionary<string, string>
{
{
DOAuthStatic.CLIENT_NAME_KEY, context.ClientId ?? string.Empty
}
};
ValidateContext(context, authResponse, props);
}
catch (Exception ex)
{
DLogOAuth.LogException(ex, "DCO0407E", "OAuthServerProvider - Error validating user");
throw;
}
}
你就要成功了,你就需要再执行两个步骤:
- 在您的方法或控制器上添加AuthorizeAttribute以限制访问未经认证的用户。
- 添加您请求标头的访问令牌。如果你跳过这一步,你应该得到一个401 HTTP状态码,意味着未经授权。这是您可以确认您在第一步中添加的授权属性的工作方式。
这里是一个伟大的系列教程,说明一切都非常好:Token based authentication(路比我更好:))
修改内容类型“应用/ JSON的”到 “应用程序/ www-form-urlencoded“
您是Postman”application/www-form-urlencoded“格式的发送数据。但是在你的代码中使用“application/Json”内容类型不匹配。所以,数据不能发送适当的格式。
如果工作正常,您可以更改。