我想實現基於web api 2的基於聲明的oauth令牌認證。爲此,我已經創建OWIN承載認證失敗的web api 2
[assembly: OwinStartup(typeof(PMW.Api.Startup))]
public class Startup
{
//private IUnitOfWork _unitOfWork;
//private IUserService _userService;
//private ICommonService _commonService;
public void Configuration(IAppBuilder app)
{
HttpConfiguration config = new HttpConfiguration();
WebApiConfig.Register(config);
app.UseCors(Microsoft.Owin.Cors.CorsOptions.AllowAll);
app.UseWebApi(config);
IUnityContainer container = GetUnityContainer();
config.DependencyResolver = new UnityDependancyResolver(container);
//_unitOfWork = container.Resolve<IUnitOfWork>();
//_userService = container.Resolve<IUserService>();
//_commonService = container.Resolve<ICommonService>();
MapAutomapper();
ConfigureOAuth(app);
//var OAuthBearerOptions = new OAuthBearerAuthenticationOptions()
//{
// Provider = new QueryStringOAuthBearerProvider(),
// AccessTokenProvider = new AuthenticationTokenProvider()
// {
// OnCreate = create,
// OnReceive = receive
// },
//};
//app.UseOAuthBearerAuthentication(OAuthBearerOptions);
}
public static Action<AuthenticationTokenCreateContext> create = new Action<AuthenticationTokenCreateContext>(c =>
{
c.SetToken(c.SerializeTicket());
});
public static Action<AuthenticationTokenReceiveContext> receive = new Action<AuthenticationTokenReceiveContext>(c =>
{
c.DeserializeTicket(c.Token);
c.OwinContext.Environment["Properties"] = c.Ticket.Properties;
});
private void MapAutomapper()
{
//Mapper code
}
private IUnityContainer GetUnityContainer()
{
//Create UnityContainer
IUnityContainer container = //unity mapping
return container;
}
public void ConfigureOAuth(IAppBuilder app)
{
OAuthAuthorizationServerOptions OAuthServerOptions = new OAuthAuthorizationServerOptions()
{
AllowInsecureHttp = true,
TokenEndpointPath = new PathString("/token"),
AccessTokenExpireTimeSpan = TimeSpan.FromDays(1),
Provider = new SimpleAuthorizationServerProvider()
};
// Token Generation
app.UseOAuthAuthorizationServer(OAuthServerOptions);
app.UseOAuthBearerAuthentication(new OAuthBearerAuthenticationOptions());
}
}
和授權類被定義爲下面
public class SimpleAuthorizationServerProvider : OAuthAuthorizationServerProvider
{
public override async Task ValidateClientAuthentication(OAuthValidateClientAuthenticationContext context)
{
context.Validated();
}
public override async Task GrantResourceOwnerCredentials(OAuthGrantResourceOwnerCredentialsContext context)
{
IUnityContainer container = //unity code for mapping login related service
var _commonService=container.Resolve<ICommonService>() ;
var password =// Encrypt password
UserService _userService = new UserService(container.Resolve<IUnitOfWork>(),
container.Resolve<IUserMasterRepository>(), container.Resolve<IUserDetailRepository>());
var userToPass = new UserDTO()
{
EmailId = context.UserName,
Password = password
};
var user = _userService.AuthenticateUser(userToPass);
if (!user.Succeeded)
{
context.SetError("invalid_grant", "The user name or password is incorrect.");
return;
}
var identity = new ClaimsIdentity(context.Options.AuthenticationType);
identity.AddClaim(new Claim(ClaimTypes.Name, context.UserName));
identity.AddClaim(new Claim(ClaimTypes.Role, "user"));
context.Validated(identity);
}
}
該代碼被適當地工作,併產生令牌的客戶端應用程序。但是,如果我使用Authrize屬性如下所示。它總是失敗,錯誤401未經授權。
[Authorize]
[HttpGet]
public UserDTO Test()
{
return new UserDTO();
}
以下是請求和失敗方法詳細信息的快照。
請讓我們知道我缺少什麼才能正確實施授權流程。
你能說明你如何從測試方法中獲取GET?我的意思是,正在發送:授權:承載者作爲請求標頭正確嗎? –
2014-12-02 16:24:35
我已經添加了包含授權承載令牌的請求部分引用的快照。 – parth1729 2014-12-03 09:03:00
從快照中的信息看來,您似乎有兩個項目:一個用於授權,另一個用於資源。你有沒有在兩個webconfig文件中檢查machinekey是否相同?檢查這個問題:http://stackoverflow.com/questions/25901414/owin-authentication-between-mvc-5-and-web-api-separate-iis-applications/25942811#25942811 – 2014-12-03 10:16:13