使用此代码:
MyAuthorizationServerProvider
public class MyAuthorizationServerProvider : OAuthAuthorizationServerProvider
{
public override async Task ValidateClientAuthentication(OAuthValidateClientAuthenticationContext context)
{
context.Validated(); //
}
public override async Task GrantResourceOwnerCredentials(OAuthGrantResourceOwnerCredentialsContext context)
{
var identity = new ClaimsIdentity(context.Options.AuthenticationType);
if (context.UserName == "admin" && context.Password == "admin")
{
identity.AddClaim(new Claim(ClaimTypes.Role, "admin"));
identity.AddClaim(new Claim("username", "admin"));
identity.AddClaim(new Claim(ClaimTypes.Name, "Juan Dela Cruz"));
context.Validated(identity);
}
else if (context.UserName == "user" && context.Password == "user")
{
identity.AddClaim(new Claim(ClaimTypes.Role, "user"));
identity.AddClaim(new Claim("username", "user"));
identity.AddClaim(new Claim(ClaimTypes.Name, "Barok Kabundukan"));
context.Validated(identity);
}
else
{
context.SetError("invalid_grant", "Provided username or password is incorrect");
return;
}
}
}
AuthorizeAttribute
protected override void HandleUnauthorizedRequest(System.Web.Http.Controllers.HttpActionContext actionContext)
{
if (!HttpContext.Current.User.Identity.IsAuthenticated)
{
base.HandleUnauthorizedRequest(actionContext);
}
else
{
actionContext.Response = new System.Net.Http.HttpResponseMessage(System.Net.HttpStatusCode.Forbidden);
}
}
启动
public class Startup
{
public void Configuration(IAppBuilder app)
{
//enable cors origin requests
app.UseCors(Microsoft.Owin.Cors.CorsOptions.AllowAll);
var myProvider = new MyAuthorizationServerProvider();
OAuthAuthorizationServerOptions options = new OAuthAuthorizationServerOptions
{
AllowInsecureHttp = true,
TokenEndpointPath = new PathString("/token"),
AccessTokenExpireTimeSpan = TimeSpan.FromDays(1),
Provider = myProvider
};
app.UseOAuthAuthorizationServer(options);
app.UseOAuthBearerAuthentication(new OAuthBearerAuthenticationOptions());
HttpConfiguration config = new HttpConfiguration();
WebApiConfig.Register(config);
}
}
DataController类
public class DataController : ApiController
{
[AllowAnonymous]
[HttpGet]
[Route("api/data/forall")]
public IHttpActionResult Get()
{
return Ok("Server time is: " + DateTime.Now);
}
[Authorize]
[HttpGet]
[Route("api/data/authenticate")]
public IHttpActionResult GetForAuthenticate()
{
var identity = (ClaimsIdentity)User.Identity;
return Ok("Hello " + identity.Name);
}
[Authorize(Roles = "admin")]
[HttpGet]
[Route("api/data/authorize")]
public IHttpActionResult GetForAdmin()
{
var identity = (ClaimsIdentity)User.Identity;
var roles = identity.Claims
.Where(c => c.Type == ClaimTypes.Role)
.Select(c => c.Value);
return Ok("Hello " + identity.Name + " Role: " + string.Join(",", roles.ToList()));
}
}
使用该代码,我可以获取令牌并进行身份验证。然而问题是当我使用"用户"凭证和身份验证然后访问具有授权(角色="管理员")的方法,在邮差中,我得到" 401"。我应该得到" 403"因为我已经过身份验证但没有#34; admin"的作用。你能告诉我哪里弄错了吗?谢谢。
答案 0 :(得分:-1)
不,你仍然应该得到401. 401意味着未经授权,而不是未经身份验证。在您的方案中,您没有管理员角色,因此您无权访问所请求的资源。
编辑: 我通常不会发布维基百科,但我认为403上的文章很好地解释了这一点;请参阅401和403之间的差异部分: