【发布时间】:2015-01-29 20:04:16
【问题描述】:
我有一个控制器,我在其中将服务接口注入到构造函数中。 该服务也将接口注入到其构造函数中。 IoC 容器 (Unity) 在构造它为给定接口返回的类之一时需要使用有关用户的信息。
发生的情况是,在评估 [Authorize] 属性和验证用户身份之前,控制器正在被实例化。这会强制 Unity 在用户登录之前执行依赖注入并使用有关用户的信息。当我们使用集成 Windows 身份验证时,这都不是问题,但现在我们使用 OpenID Connect to Azure AD 并且用户信息不是t 在那里,直到他们登录(这发生在控制器启动之后)。
我听说(在其他帖子中)有一种方法可以配置我的 owin 启动类以在此过程中更早地移动身份验证,但我找不到任何有关如何执行此操作的示例。我需要在实例化控制器之前进行身份验证。
这是我所拥有的一个简化示例...
控制器:
[Authorize]
public class MyController : Controller
{
private readonly IMyService myService;
public MyController(IMyService myService)
{
this.myService = myService;
}
// ...
}
统一配置:
public class UnityBootstrap : IUnityBootstrap
{
public IUnityContainer Configure(IUnityContainer container)
{
// ...
return container
.RegisterType<ISomeClass, SomeClass>()
.RegisterType<IMyService>(new InjectionFactory(c =>
{
// gather info about the user here
// e.g.
var currentUser = c.Resolve<IPrincipal>();
var staff = c.Resolve<IStaffRepository>().GetBySamAccountName(currentUser.Identity.Name);
return new MyService(staff);
}));
}
}
OWIN 启动 (Startup.Auth.cs):
public void ConfigureAuth(IAppBuilder app)
{
app.SetDefaultSignInAsAuthenticationType(CookieAuthenticationDefaults.AuthenticationType);
app.UseCookieAuthentication(new CookieAuthenticationOptions());
app.UseOpenIdConnectAuthentication(
new OpenIdConnectAuthenticationOptions
{
ClientId = this.clientID,
Authority = this.authority,
PostLogoutRedirectUri = this.postLogoutRedirectUri,
Notifications = new OpenIdConnectAuthenticationNotifications
{
RedirectToIdentityProvider = context =>
{
context.ProtocolMessage.DomainHint = this.domainHint;
return Task.FromResult(0);
},
AuthorizationCodeReceived = context =>
{
var code = context.Code;
var credential = new ClientCredential(this.clientID, this.appKey.Key);
var userObjectID = context.AuthenticationTicket.Identity.FindFirst("http://schemas.microsoft.com/identity/claims/objectidentifier").Value;
var authContext = new AuthenticationContext(this.authority, new NaiveSessionCache(userObjectID));
var result = authContext.AcquireTokenByAuthorizationCode(code, new Uri(HttpContext.Current.Request.Url.GetLeftPart(UriPartial.Path)), credential, this.graphUrl);
AzureAdGraphAuthenticationHelper.Token = result.AccessToken;
return Task.FromResult(0);
}
}
});
}
【问题讨论】:
-
我也被这个绊倒了,虽然没有任何 DI 的东西。在基本控制器的构造函数中需要一个 userId,并且惊讶地看到构造函数在
AuthorizedAttribute移动用户之前被调用。
标签: c# asp.net-mvc authentication openid owin