[英]Local account and option for Azure AD authentication using IdentityServer3
I'm new to IdentityServer. 我是IdentityServer的新手。 We have a requirement for the application to allow access to multiple web APIs. 我们要求该应用程序允许访问多个Web API。 As of now authentication is done locally with a database and there is alternate way to get authenticated by Azure AD. 到目前为止,身份验证是使用数据库在本地完成的,还有另一种方法可以通过Azure AD进行身份验证。
I want my dashboard app to authenticate using IdentityServer3 (which is working fine as of now) and alternatively using external provider (Azure AD in this case). 我希望我的仪表板应用程序使用IdentityServer3(到目前为止可以正常工作)进行身份验证,或者使用外部提供程序(在这种情况下为Azure AD)进行身份验证。
However I keep getting 但是我不断
There is an error determining which application you are signing into. 确定您要登录的应用程序时出错。 Return to the application and try again 返回应用程序,然后重试
The configuration for server, I'm using CustomViewService found at here 服务器的配置,我使用的是在此处找到的 CustomViewService
I'm adding Azure AD to the list of external providers: 我将Azure AD添加到外部提供商列表中:
app.UseOpenIdConnectAuthentication(new OpenIdConnectAuthenticationOptions
{
ClientId = "xxxxxx-xxx-xxx-xx-04ec8dbxxxx",
Authority = "https://login.windows.net/[domain name]",
RedirectUri = "https://localhost:44333/core",
PostLogoutRedirectUri = "http://localhost:36336/",
AuthenticationType = "Azure AD",
Caption = "Azure AD",
TokenValidationParameters = new TokenValidationParameters
{
NameClaimType = "name",
RoleClaimType = "role"
},
SignInAsAuthenticationType = "Cookies",
Notifications = new OpenIdConnectAuthenticationNotifications
{
MessageReceived = m =>
{
var split = m.ProtocolMessage.AccessToken;
return Task.FromResult(0);
},
AuthenticationFailed = context =>
{
context.HandleResponse();
context.Response.Redirect("/Error?message=" + context.Exception.Message);
return Task.FromResult(0);
},
RedirectToIdentityProvider = (context) =>
{
context.ProtocolMessage.DomainHint = "[domain name here]";
return Task.FromResult(0);
}
}
});
I'm presented with Azure AD log in screen, after which application is diverted back to IdentityServ3 at https://localhost:44333/core/callback
在屏幕上显示了Azure AD登录屏幕,然后将应用程序转移回https://localhost:44333/core/callback
IdentityServ3
My client is at http://localhost:36336/
我的客户位于http://localhost:36336/
Client configuration is: 客户端配置为:
public void Configuration(IAppBuilder app)
{
// For more information on how to configure your application, visit http://go.microsoft.com/fwlink/?LinkID=316888
JwtSecurityTokenHandler.InboundClaimTypeMap = new Dictionary<string, string>();
app.UseCookieAuthentication(new CookieAuthenticationOptions
{
AuthenticationType = "Cookies"
});
app.UseOpenIdConnectAuthentication(new OpenIdConnectAuthenticationOptions
{
ClientId = "mvc.owin.hybrid.2",
Authority = "https://localhost:44333/core",
RedirectUri = "http://localhost:36336/",
PostLogoutRedirectUri = "http://localhost:36336/",
ResponseType = "code id_token",
Scope = "openid profile read write offline_access",
TokenValidationParameters = new TokenValidationParameters
{
NameClaimType = "name",
RoleClaimType = "role"
},
SignInAsAuthenticationType = "Cookies",
Notifications = new OpenIdConnectAuthenticationNotifications
{
AuthorizationCodeReceived = async n =>
{
// use the code to get the access and refresh token
var tokenClient = new TokenClient(
"https://localhost:44333/core/connect/token",
"mvc.owin.hybrid.2",
"secret");
var tokenResponse = await tokenClient.RequestAuthorizationCodeAsync(
n.Code, n.RedirectUri);
if (tokenResponse.IsError)
{
throw new Exception(tokenResponse.Error);
}
// use the access token to retrieve claims from userinfo
var userInfoClient = new UserInfoClient(
new Uri(n.Options.Authority + "/connect/userinfo"),
tokenResponse.AccessToken);
var userInfoResponse = await userInfoClient.GetAsync();
// create new identity
var id = new ClaimsIdentity(n.AuthenticationTicket.Identity.AuthenticationType);
id.AddClaims(userInfoResponse.GetClaimsIdentity().Claims);
id.AddClaim(new Claim("access_token", tokenResponse.AccessToken));
id.AddClaim(new Claim("expires_at", DateTime.Now.AddSeconds(tokenResponse.ExpiresIn).ToLocalTime().ToString()));
id.AddClaim(new Claim("refresh_token", tokenResponse.RefreshToken));
id.AddClaim(new Claim("id_token", n.ProtocolMessage.IdToken));
id.AddClaim(new Claim("sid", n.AuthenticationTicket.Identity.FindFirst("sid").Value));
n.AuthenticationTicket = new AuthenticationTicket(
new ClaimsIdentity(id.Claims, n.AuthenticationTicket.Identity.AuthenticationType, "name", "role"),
n.AuthenticationTicket.Properties);
},
RedirectToIdentityProvider = n =>
{
// if signing out, add the id_token_hint
if (n.ProtocolMessage.RequestType == OpenIdConnectRequestType.LogoutRequest)
{
var idTokenHint = n.OwinContext.Authentication.User.FindFirst("id_token");
if (idTokenHint != null)
{
n.ProtocolMessage.IdTokenHint = idTokenHint.Value;
}
}
return Task.FromResult(0);
}
}
});
}
Managed to work it out. 设法解决。
I forgot to implement AspNetIdentityUserService
specially the method AuthenticateExternalAsync
我忘了特别地实现AspNetIdentityUserService
方法AuthenticateExternalAsync
Once I mapped the user and claims from Azure to the local user it worked. 一旦将用户映射并从Azure声明到本地用户,它就可以工作。
Furthermore, if you need to hide local login screen and want your client to directly go to Azure AD login screen make sure to set EnableLocalLogin
to false in Client properties 此外,如果您需要隐藏本地登录屏幕并希望您的客户端直接转到Azure AD登录屏幕,请确保在客户端属性中将EnableLocalLogin
设置为false
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.