在我的web api应用程序中,我实现了OAuth2。在ApplicationOAuthProvider的GrantResourceOwnerCredentials上,我正在调用我的自定义成员资格服务来登录并获取令牌。问题是我必须将成员资格服务注入ApplicationOAuthProvider才能使用该服务,但由于owinStartup类它没有允许它不支持参数构造函数。如何在GrantResourceOwnerCredentials方法中注入/使用我的会员服务。
public class ApplicationOAuthProvider : OAuthAuthorizationServerProvider
{
private readonly string _publicClientId;
private readonly IMembershipService _membershipService;
public ApplicationOAuthProvider(string publicClientId,
IMembershipService membershipService)
{
if (publicClientId == null)
{
throw new ArgumentNullException("publicClientId");
}
_publicClientId = publicClientId;
this._membershipService = membershipService;
}
public override async Task GrantResourceOwnerCredentials(OAuthGrantResourceOwnerCredentialsContext context)
{
AccountLogin LogCredentials = new AccountLogin();
LogCredentials.UserName = context.UserName;
LogCredentials.Password = context.Password;
ProviderLoginResponse providerLoginResponse =
_membershipService.UserLogin(LogCredentials);
if (providerLoginResponse.LoginStatus != "Y")
{
context.SetError("invalid_grant", "The user name or password
is incorrect.");
return;
}
var claims = new List<Claim>()
{
new Claim(ClaimTypes.Sid, Convert.ToString(1)),
new Claim(ClaimTypes.Name, providerLoginResponse.UserName),
new Claim(ClaimTypes.Email, providerLoginResponse.UserEmail)
};
ClaimsIdentity oAuthIdentity = new ClaimsIdentity(claims,
Startup.OAuthOptions.AuthenticationType);
AuthenticationProperties properties = CreateProperties(context.UserName);
AuthenticationTicket ticket = new AuthenticationTicket(oAuthIdentity, properties);
context.Validated(ticket);
}
}
我的owin启动课程:
public partial class Startup
{
private readonly IMembershipService _membershipService;
//This will cause a runtime error owin startup class only support parameterless constructor
public Startup(IMembershipService membershipService)
{
this._membershipService = membershipService;
}
public void ConfigureAuth(IAppBuilder app)
{
OAuthOptions = new OAuthAuthorizationServerOptions
{
TokenEndpointPath = new PathString("/Token"),
//Here passing the _membershipService to ApplicationOAuthProvider constructor
Provider = new ApplicationOAuthProvider(PublicClientId,_membershipService ),
AuthorizeEndpointPath = new PathString("/api/Account/ExternalLogin"),
AccessTokenExpireTimeSpan = TimeSpan.FromDays(14),
// In production mode set AllowInsecureHttp = false
AllowInsecureHttp = true
};
}
}
答案 0 :(得分:5)
一种解决方案是将依赖性解析器作为静态变量存储在例如Startup.cs类中,然后针对该解析器解析接口。
当你用MVC标记这个问题时,我猜你有Full.asax文件和Startup.cs类。 Global.asax将在Startup.cs之前执行,我们可以在此解决方案中使用。
在此解决方案中,我使用Unity作为容器,但您可以使用您喜欢的任何内容。
在Startup.cs类
中声明静态变量public partial class Startup
{
public static UnityContainer IoC { get; set; }
...
然后在WebApiConfig.Register()方法中,解析器附加到当前的HttpConfiguration,同时在Startup.cs中设置变量(注意这将在Startup.cs类之前调用)
public static class WebApiConfig
{
public static void Register(HttpConfiguration config)
{
// Web API routes
config.MapHttpAttributeRoutes();
config.Routes.MapHttpRoute(
name: "DefaultApi",
routeTemplate: "api/{controller}/{id}",
defaults: new { id = RouteParameter.Optional }
);
var container = new UnityContainer();
//register all your interfaces in the container
container.RegisterType<IMembershipService, MembershipService>(new HierarchicalLifetimeManager());
Startup.IoC = container;
config.DependencyResolver = new UnityResolver(Startup.IoC);
}
}
然后在Startup.cs中使用它
public partial class Startup
{
public static UnityContainer IoC { get; set; }
public void ConfigureAuth(IAppBuilder app)
{
OAuthOptions = new OAuthAuthorizationServerOptions
{
TokenEndpointPath = new PathString("/Token"),
//Resolve the interface here
Provider = new ApplicationOAuthProvider(PublicClientId, Startup.IoC.Resolve<IMembershipService>() ),
AuthorizeEndpointPath = new PathString("/api/Account/ExternalLogin"),
AccessTokenExpireTimeSpan = TimeSpan.FromDays(14),
// In production mode set AllowInsecureHttp = false
AllowInsecureHttp = true
};
}
}