我已经构建了一个Web应用程序。当我建立它时,我勾选了“组织帐户”
效果很好 - 我使用Office 365帐户登录,User.Identity.Name
包含电子邮件地址
此应用程序是旧版ASP Classic应用程序的替代前端。该应用程序有一个我需要使用的现有安全表。
我想使用电子邮件地址查找此表中的记录以获取
用户的内部数据库密钥(因此我可以在数据库调用中使用它)
用户的安全级别(授权)
我想在通过身份验证后立即查看,并将这两个值保存到Session
以便稍后引用
我有一个现有的方法来执行所有这些查找和缓存。我实际上通过从_LoginPartial.cshtml
视图调用它来实现它,但显然从视图中触发这种事情是不正确的
这是查找和缓存用户信息的代码。现在这是AccountController.cs
,但不一定是
private Boolean GetAdditionalUserInfo()
{
// if authentication info is saved, don't go find it
if (Session["UID"] != null) return true;
// get the db employee id from the database and save it to the session
var r = (
from e in db.Employees
where e.Email == User.Identity.Name
select new
{
e.Emp_ID,
e.Group_ID
}
).SingleOrDefault();
if ((r == null) || (r.Group_ID == (int)Role.Inactive))
{
// couldn't find record or inactive
return false;
}
// Update last login datetime
Employee ell = db.Employees.Find(r.Emp_ID);
ell.LastLogin = DateTime.Now;
db.SaveChangesAsync();
// Save user details to the session
Session["UID"] = r.Emp_ID;
// TBD: Investigate "CLAIMS" - this should probably be a claim
Session["Role"] = r.Group_ID;
return true;
}
我认为对User.Identity.Name
的引用会触发登录过程,所以我可以尝试在启动时调用它(我不知道这样做的正确方法),或者我认为做正确的事情是使用OnAuthentication
方法调用它,并将其链接起来我应该将我的函数名称传递给OnAuthenticated
属性。这是方法和属性的两个链接:
https://msdn.microsoft.com/en-us/library/system.web.mvc.controller.onauthentication(v=vs.118).aspx
但我必须说OO编程不是我的事情,我无法从这些页面中找到如何使用它们或将它们放入哪个类。
这page意味着需要进入Startup.Auth.cs
,但我的Startup.Auth.cs
看起来不像那个。这是我Startup.Auth.cs
的大部分内容,当我在开始时勾选“组织”时,它主要是自动生成的。 (另一方面,app.UseKentorOwinCookieSaver();
是我的下一个挑战,因为显然组织登录无法与Session
一起使用,你能相信它吗!!!)
有人可以帮我添加所需的代码来致电GetAdditionalUserInfo()
吗?登录后?或者确认我可以在启动时调用它,并建议正确的方法。
public partial class Startup
{
private static string clientId = ConfigurationManager.AppSettings["ida:ClientId"];
private static string aadInstance = ConfigurationManager.AppSettings["ida:AADInstance"];
private static string tenantId = ConfigurationManager.AppSettings["ida:TenantId"];
private static string postLogoutRedirectUri = ConfigurationManager.AppSettings["ida:PostLogoutRedirectUri"];
//private static string authority = aadInstance + tenantId;
// to make this multi tenant, use common endpoint, not the tenant specific endpoint
private static string authority = aadInstance + "common";
public void ConfigureAuth(IAppBuilder app)
{
app.SetDefaultSignInAsAuthenticationType(
CookieAuthenticationDefaults.AuthenticationType);
// https://stackoverflow.com/questions/20737578/asp-net-sessionid-owin-cookies-do-not-send-to-browser
app.UseKentorOwinCookieSaver();
app.UseCookieAuthentication(
new CookieAuthenticationOptions());
app.UseOpenIdConnectAuthentication(
new OpenIdConnectAuthenticationOptions
{
ClientId = clientId,
Authority = authority,
PostLogoutRedirectUri = postLogoutRedirectUri,
TokenValidationParameters = new TokenValidationParameters
{
// If you don't add this, you get IDX10205
// from here http://charliedigital.com/2015/03/14/adding-support-for-azure-ad-login-o365-to-mvc-apps/
ValidateIssuer = false
},
Notifications = new OpenIdConnectAuthenticationNotifications
{
RedirectToIdentityProvider = ctx =>
{
bool isAjaxRequest = (ctx.Request.Headers != null && ctx.Request.Headers["X-Requested-With"] == "XMLHttpRequest");
if (isAjaxRequest)
{
ctx.Response.Headers.Remove("Set-Cookie");
ctx.State = NotificationResultState.HandledResponse;
}
return System.Threading.Tasks.Task.FromResult(0);
}
}
});
}
}
答案 0 :(得分:4)
在文章The OWIN OpenID Connect Middleware中,您可以找到有关如何使用Notifications
的详细说明。在您的情况下,您应该订阅SecurityTokenValidated
:
RedirectToIdentityProvider = ctx => {...},
SecurityTokenValidated = (context) =>
{
string userID = context.AuthenticationTicket.Identity.FindFirst(ClaimTypes.NameIdentifier).Value;
// Here you can retrieve information from Database. Let's say you get r.Group_ID.
var role = r.Group_ID;
// You can now add it to Identity and no need to use session.
Claim roleClaim = new Claim(
"http://nomatterwhatyouput/role",
role,
ClaimValueTypes.[RoleType],
"LocalAuthority");
context.AuthenticationTicket.Identity.AddClaim(roleClaim);
// Do same for all values you have. Remember to set unique claim URL for each value.
return Task.CompletedTask;
},
然后您可以在该文章中提到的操作中检索这些值:
public ActionResult Index()
{
var role = ClaimsPrincipal.Current.FindFirst("http://nomatterwhatyouput/role");
return View();
}