C# 仅将Azure AD用于身份验证,而不用于授权
这件事我已经搞了好几天了 我想做的是使用Azure AD对用户进行身份验证,成功后,使用ASP.NET身份自动登录以进行授权。如果他们没有帐户,我想自动创建一个 本质上,Azure AD只是确认他们是组织的一部分,ASP.NET标识部分是它自己的数据库,我可以使用C# 仅将Azure AD用于身份验证,而不用于授权,c#,asp.net,azure,asp.net-identity,azure-active-directory,C#,Asp.net,Azure,Asp.net Identity,Azure Active Directory,这件事我已经搞了好几天了 我想做的是使用Azure AD对用户进行身份验证,成功后,使用ASP.NET身份自动登录以进行授权。如果他们没有帐户,我想自动创建一个 本质上,Azure AD只是确认他们是组织的一部分,ASP.NET标识部分是它自己的数据库,我可以使用[Authorize]属性在Azure AD之外设置自定义角色 这是我的ConfigureAuth()方法: public void ConfigureAuth(IAppBuilder app) { // Con
[Authorize]
属性在Azure AD之外设置自定义角色
这是我的ConfigureAuth()
方法:
public void ConfigureAuth(IAppBuilder app)
{
// Configure the db context, user manager and signin manager to use a single instance per request
app.CreatePerOwinContext(IntranetApplicationDbContext.Create);
app.CreatePerOwinContext<ApplicationUserManager>(ApplicationUserManager.Create);
app.CreatePerOwinContext<ApplicationSignInManager>(ApplicationSignInManager.Create);
app.SetDefaultSignInAsAuthenticationType(CookieAuthenticationDefaults.AuthenticationType);
app.UseCookieAuthentication(new CookieAuthenticationOptions());
app.UseOpenIdConnectAuthentication(
new OpenIdConnectAuthenticationOptions
{
ClientId = SettingsHelper.ClientId,
Authority = SettingsHelper.Authority,
Notifications = new OpenIdConnectAuthenticationNotifications()
{
// If there is a code in the OpenID Connect response, redeem it for an access token and refresh token, and store those away.
AuthorizationCodeReceived = (context) =>
{
var code = context.Code;
ClientCredential credential = new ClientCredential(SettingsHelper.ClientId, SettingsHelper.AppKey);
String signInUserId = context.AuthenticationTicket.Identity.FindFirst(ClaimTypes.NameIdentifier).Value;
AuthenticationContext authContext = new AuthenticationContext(SettingsHelper.Authority, new ADALTokenCache(signInUserId));
AuthenticationResult result = authContext.AcquireTokenByAuthorizationCode(code, new Uri(HttpContext.Current.Request.Url.GetLeftPart(UriPartial.Path)), credential, SettingsHelper.AADGraphResourceId);
return Task.FromResult(0);
},
RedirectToIdentityProvider = (context) =>
{
// This ensures that the address used for sign in and sign out is picked up dynamically from the request
// this allows you to deploy your app (to Azure Web Sites, for example)without having to change settings
// Remember that the base URL of the address used here must be provisioned in Azure AD beforehand.
string appBaseUrl = context.Request.Scheme + "://" + context.Request.Host + context.Request.PathBase;
context.ProtocolMessage.RedirectUri = appBaseUrl + "/";
context.ProtocolMessage.PostLogoutRedirectUri = appBaseUrl;
return Task.FromResult(0);
},
AuthenticationFailed = (context) =>
{
// Suppress the exception if you don't want to see the error
context.HandleResponse();
return Task.FromResult(0);
}
}
});
// Enable the application to use a cookie to store information for the signed in user
// and to use a cookie to temporarily store information about a user logging in with a third party login provider
// Configure the sign in cookie
app.UseCookieAuthentication(new CookieAuthenticationOptions
{
AuthenticationType = DefaultAuthenticationTypes.ApplicationCookie,
LoginPath = new PathString("/Account/Login"),
Provider = new CookieAuthenticationProvider
{
// Enables the application to validate the security stamp when the user logs in.
// This is a security feature which is used when you change a password or add an external login to your account.
OnValidateIdentity = SecurityStampValidator.OnValidateIdentity<ApplicationUserManager, ApplicationUser>(
validateInterval: TimeSpan.FromMinutes(30),
regenerateIdentity: (manager, user) => user.GenerateUserIdentityAsync(manager))
},
});
}
public void ConfigureAuth(IAppBuilder应用程序)
{
//将数据库上下文、用户管理器和登录管理器配置为每个请求使用一个实例
app.CreatePerOwinContext(IntranetApplicationDbContext.Create);
app.CreatePerOwinContext(ApplicationUserManager.Create);
app.CreatePerOwinContext(ApplicationSignInManager.Create);
app.SetDefaultSignInAsAuthenticationType(CookieAuthenticationDefaults.AuthenticationType);
app.UseCookieAuthentication(新的CookieAuthenticationOptions());
app.UseOpenIdConnectAuthentication(
新的OpenIdConnectAuthenticationOptions
{
ClientId=设置shelper.ClientId,
权限=设置搁置权限,
通知=新的OpenIdConnectAuthenticationNotifications()
{
//如果OpenID Connect响应中有代码,请将其兑换为访问令牌和刷新令牌,并将其存储起来。
AuthorizationCodeReceived=(上下文)=>
{
var code=context.code;
ClientCredential credential=新的ClientCredential(SettingsHelper.ClientId,SettingsHelper.AppKey);
String signInUserId=context.AuthenticationTicket.Identity.FindFirst(ClaimTypes.NameIdentifier).Value;
AuthenticationContext authContext=新的AuthenticationContext(SettingsHelper.Authority,新的ADALTokenCache(signInUserId));
AuthenticationResult=authContext.AcquireTokenByAuthorizationCode(代码,新Uri(HttpContext.Current.Request.Url.GetLeftPart(Uriplate.Path)),凭证,设置Shelper.AADGraphResourceId);
返回Task.FromResult(0);
},
RedirectToIdentityProvider=(上下文)=>
{
//这样可以确保从请求中动态提取用于登录和注销的地址
//这允许您部署应用程序(例如,部署到Azure网站),而无需更改设置
//请记住,此处使用的地址的基本URL必须事先在Azure AD中设置。
字符串appBaseUrl=context.Request.Scheme+“:/”+context.Request.Host+context.Request.PathBase;
context.ProtocolMessage.RedirectUri=appBaseUrl+“/”;
context.ProtocolMessage.PostLogoutRedirectUri=appBaseUrl;
返回Task.FromResult(0);
},
身份验证失败=(上下文)=>
{
//如果不想看到错误,请抑制异常
context.HandleResponse();
返回Task.FromResult(0);
}
}
});
//使应用程序能够使用cookie存储登录用户的信息
//以及使用cookie临时存储用户登录第三方登录提供商的信息
//配置登录cookie
app.UseCookieAuthentication(新的CookieAuthenticationOptions
{
AuthenticationType=DefaultAuthenticationTypes.ApplicationOkie,
LoginPath=新路径字符串(“/Account/Login”),
Provider=新CookieAuthenticationProvider
{
//允许应用程序在用户登录时验证安全戳。
//这是一种安全功能,在您更改密码或向帐户添加外部登录时使用。
OnValidateIdentity=SecurityStampValidator.OnValidateIdentity(
validateInterval:TimeSpan.FromMinutes(30),
regenerateIdentity:(管理器,用户)=>user.GenerateUserIdentityAsync(管理器))
},
});
}
现在,当我执行HttpContext.Request.IsAuthenticated
时,ASP.NET身份正在接管。这没关系,我只需要一种方法来检查OpenID部分是否经过身份验证,这样我就可以输入自定义逻辑来自动登录用户。明白了
我最大的问题是试图使用OWIN中间件为我做任何事情。对Azure AD的简单身份验证不需要OpenID中间件。我实际上在Account controller中创建了一个OpenIdAuth
方法,它充当我的中间人,在用户访问该站点之前向Azure进行身份验证
[AllowAnonymous]
public ActionResult OpenIdAuth(string code)
{
string clientId = "00000000-0000-0000-0000-000000000000"; // Client ID found in the Azure AD Application
string appKey = "111111111112222222222223333333333AAABBBCCC="; // Key generated in the Azure AD Appliction
if (code != null)
{
string commonAuthority = "https://login.windows.net/<TENANT_URL>"; // Eg. https://login.windows.net/MyDevSite.onmicrosoft.com
var authContext = new AuthenticationContext(commonAuthority);
ClientCredential credential = new ClientCredential(clientId, appKey);
AuthenticationResult authenticationResult = authContext.AcquireTokenByAuthorizationCode(code, new Uri(HttpContext.Request.Url.GetLeftPart(UriPartial.Path)), credential, "https://graph.windows.net");
var userManager = HttpContext.GetOwinContext().GetUserManager<ApplicationUserManager>();
var signInManager = HttpContext.GetOwinContext().Get<ApplicationSignInManager>();
var user = UserManager.FindByName(authenticationResult.UserInfo.UniqueId);
if (user != null)
{
signInManager.SignIn(user, false, false);
}
else
{
var newUser = new ApplicationUser { UserName = authenticationResult.UserInfo.UniqueId, Email = authenticationResult.UserInfo.DisplayableId };
var creationResult = UserManager.Create(newUser);
if (creationResult.Succeeded)
{
user = UserManager.FindByName(newUser.UserName);
signInManager.SignIn(user, false, false);
}
else
{
return new ViewResult { ViewName = "Error" };
}
}
return Redirect("/");
}
else
{
var url = new Uri($"https://login.microsoftonline.com/<TENANT_URL>/oauth2/authorize?client_id={clientId}&response_type=code&redirect_uri=https://localhost/Account/OpenIdAuth");
return Redirect(url.AbsoluteUri);
}
}
我想说的是,你不应该寻找OpenID,而应该寻找并使用类似的东西。事实上,我昨天刚刚浏览了那篇文章,Azure广告组很笨重,不像ASP.NET身份角色那样流畅。我希望应用程序用户能够动态地更改角色,而无需在Active Directory中进行更改。您所指的应用程序密钥,这是Azure应用程序中生成的sescret吗?@NiAu-Yup!这个秘密来自于你在Azure广告中创建新的应用注册
public void ConfigureAuth(IAppBuilder app)
{
// Configure the db context, user manager and signin manager to use a single instance per request
app.CreatePerOwinContext(IntranetApplicationDbContext.Create);
app.CreatePerOwinContext<ApplicationUserManager>(ApplicationUserManager.Create);
app.CreatePerOwinContext<ApplicationSignInManager>(ApplicationSignInManager.Create);
// Enable the application to use a cookie to store information for the signed in user
// and to use a cookie to temporarily store information about a user logging in with a third party login provider
// Configure the sign in cookie
app.UseCookieAuthentication(new CookieAuthenticationOptions
{
AuthenticationType = DefaultAuthenticationTypes.ApplicationCookie,
LoginPath = new PathString("/Account/Login"),
Provider = new CookieAuthenticationProvider
{
// Enables the application to validate the security stamp when the user logs in.
// This is a security feature which is used when you change a password or add an external login to your account.
OnValidateIdentity = SecurityStampValidator.OnValidateIdentity<ApplicationUserManager, ApplicationUser>(
validateInterval: TimeSpan.FromMinutes(30),
regenerateIdentity: (manager, user) => user.GenerateUserIdentityAsync(manager))
},
});
}