gpt4 book ai didi

c# - 使用 Azure AD 进行身份验证,但使用 aspnetmembership 角色和声明进行授权

转载 作者:行者123 更新时间:2023-12-05 05:54:02 24 4
gpt4 key购买 nike

我正在尝试构建一个使用 Azure AD 进行身份验证的 ASP.NET MVC 5 应用程序。但是一旦用户通过身份验证,我需要使用 aspnet_membership Microsoft Identity 设置来获取该经过身份验证的登录用户的声明。我们不想在 Azure AD 设置中维护角色和声明,也不想使用 MS Graph。

我在 VS 2017 中使用个人用户帐户创建了一个 MVC 5.0 项目,它又在我的 SQL Server 数据库中为我创建了 aspnet_membership 数据库。

我还创建了一个单独的 MVC 5.0 项目并在 Azure AD 中注册了该应用程序,我有 ClientID 等,该项目也运行良好。现在我正试图将两者合并,但我有点迷茫,怀疑我的想法是否正确。

基本上,一旦用户登录到该 Microsoft Azure AD 登录页面,我就会重定向到本地注册页面,当用户注册时只使用包括一些角色在内的最少信息,然后我会在 AspNetUsers/Claims 中输入一个条目表,我必须将这些声明附加到委托(delegate)人。在该用户的后续登录中,我必须在通过身份验证后加载 clam。

能否请您帮我指出此类场景的任何示例,因为我在这里阅读的大部分内容都建议使用 Microsoft Graph。但是我们的角色太复杂了,我们决定只使用本地身份 aspnet_membership 数据库进行授权(角色作为声明)。

谢谢

最佳答案

这对我有用。

public partial class Startup
{
public void ConfigureAuth(IAppBuilder app)
{
string clientId = System.Configuration.ConfigurationManager.AppSettings["ClientId"];
string redirectUri = System.Configuration.ConfigurationManager.AppSettings["RedirectUri"];
string tenant = System.Configuration.ConfigurationManager.AppSettings["Tenant"];
string authority = string.Format(System.Configuration.ConfigurationManager.AppSettings["Authority"], tenant);
var cookieExpiryHours = Int32.Parse(System.Configuration.ConfigurationManager.AppSettings["CookieExpiryHours"]);

app.SetDefaultSignInAsAuthenticationType(CookieAuthenticationDefaults.AuthenticationType);
app.UseCookieAuthentication(new CookieAuthenticationOptions
{
CookieManager = new SystemWebCookieManager(),
ExpireTimeSpan = TimeSpan.FromMinutes(cookieExpiryHours),
SlidingExpiration=true,
});

app.UseOpenIdConnectAuthentication(
new OpenIdConnectAuthenticationOptions
{
ClientId = clientId,
Authority = authority,
RedirectUri = redirectUri,
PostLogoutRedirectUri = redirectUri,
Scope = OpenIdConnectScope.OpenIdProfile,
UseTokenLifetime = false,
// ResponseType is set to request the code id_token - which contains basic information about the signed-in user
ResponseType = OpenIdConnectResponseType.CodeIdToken,
TokenValidationParameters = new TokenValidationParameters()
{
ValidateIssuer = true
},

Notifications = new OpenIdConnectAuthenticationNotifications
{
AuthenticationFailed = OnAuthenticationFailed,
SecurityTokenValidated = OnSecurityTokenValidated,
}
}

);

}

private Task OnSecurityTokenValidated(SecurityTokenValidatedNotification<OpenIdConnectMessage, OpenIdConnectAuthenticationOptions> context)
{
var OIDClaimDesc = "http://schemas.microsoft.com/identity/claims/objectidentifier";
var claims = context.AuthenticationTicket.Identity.Claims;
var cookieExpiryHours = Int32.Parse(System.Configuration.ConfigurationManager.AppSettings["CookieExpiryHours"]);

context.AuthenticationTicket.Properties.ExpiresUtc = DateTimeOffset.UtcNow.AddHours(cookieExpiryHours);
context.AuthenticationTicket.Properties.IsPersistent = false;

var owinContext = context.OwinContext;
var userIdentity = context.AuthenticationTicket.Identity;
var userClaims = userIdentity as ClaimsIdentity;

var firstName = userClaims?.FindFirst(ClaimTypes.GivenName)?.Value ?? string.Empty;
var lastName = userClaims?.FindFirst(ClaimTypes.Surname)?.Value ?? string.Empty;
var email = userClaims?.FindFirst(ClaimTypes.Email)?.Value ?? string.Empty;
var objID = Guid.Parse(userClaims.FindFirst(OIDClaimDesc).Value);
var user = new UserService().GetUser(objID, email);

if (user is null)//This user has just wandered in to the site or the admins have not added this user in the DB yet. Just redirect them back to log out
{
owinContext.Authentication.Challenge();
return Task.FromResult(0);
}

if (userIdentity.IsAuthenticated)
{
userIdentity.AddClaim(new Claim(ClaimTypes.GivenName, firstName));
userIdentity.AddClaim(new Claim(ClaimTypes.Surname, lastName));
userIdentity.AddClaim(new Claim(ClaimTypes.Email, email));
userIdentity.AddClaim(new Claim("AzureID", objID.ToString()));
userIdentity.AddClaim(new Claim(ClaimTypes.Role, "user"));
}

new UserService().UpdateUser(objID, firstName, lastName, email);

foreach (var claim in user.UserClaims)
{
if (!claim.ClaimType.Equals(ClaimTypes.GivenName, StringComparison.OrdinalIgnoreCase)
&& !claim.ClaimType.Equals(ClaimTypes.Surname, StringComparison.OrdinalIgnoreCase))
{
userIdentity.AddClaim(new Claim(ClaimTypes.Role, claim.ClaimValue));
}
}

return Task.FromResult(0);
}

/// <summary>
/// Handle failed authentication requests by redirecting the user to the home page with an error in the query string
/// </summary>
/// <param name="context"></param>
/// <returns></returns>
private Task OnAuthenticationFailed(AuthenticationFailedNotification<OpenIdConnectMessage, OpenIdConnectAuthenticationOptions> context)
{
var code = "IDX21323";
if (context.Exception.Message.Contains(code)) //I need this, as under certain conditions, the auth process was going on an infinite loop.
{
context.HandleResponse();
context.OwinContext.Authentication.Challenge();
}

return Task.FromResult(true);
}
}

public UserViewModel GetUser(Guid guid, string email)
{
var model = new UserViewModel();
using (var ctxt = new DBContext())
{
var user = ctxt.Users.Where(x => (x.Email == email || x.OID==guid) && x.IsActive).FirstOrDefault();
if (user == null)
return null;
var claims = ctxt.UserClaims.Where(x => x.UserId==user.ID).ToList();
model = Mapper.Map<UserViewModel>(user);
model.UserClaims = Mapper.Map<List<ViewModels.UserClaimViewModel>>(claims);
}


return model;
}

关于c# - 使用 Azure AD 进行身份验证,但使用 aspnetmembership 角色和声明进行授权,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/69745194/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com