我必须将我在.net 4.5中编写的现有MVC项目连接到IdentityServer4。昨天我尝试了这个解决方案:https://stackoverflow.com/a/39771372,它正在运行,但我需要处理回调并从客户端应用数据库加载其他用户数据。我已尝试将 RedirectUri 更改为我自己的Controller方法,但未调用它。
今天我尝试使用示例中的Implicit Flow:https://github.com/IdentityServer/IdentityServer4.Samples/tree/release/Clients/src/MvcManual - 我知道样本是net.core,但现在我可以处理来自IdentityServer的回调。现在我该如何验证令牌?我有整个 ValidateIdentityToken 方法的问题
我使用以下方法解码了令牌:
var token = new JwtSecurityToken(jwtEncodedString: idToken);
在令牌中我找到了我的用户信息,但我认为这不是安全的方法。
最后我有两个问题:
我可以简单地将我的客户端配置为重定向到我的控制器方法,在那里我加载其他用户数据,例如" sitemap"从数据库?可以使用第一个样本吗?
使用第二个示例,任何人都知道如何验证net4.5客户端中的令牌? 验证后,我只需要主题和用户名来加载其他数据。
编辑:我的配置
a)混合
new Client
{
ClientName = "mvc Client",
ClientId = "mvc",
AllowedGrantTypes = GrantTypes.HybridAndClientCredentials,
RedirectUris = { "http://localhost:5002/Account/Callback" }, // where to redirect to after login
PostLogoutRedirectUris = { "http://localhost:5002/signout-callback-oidc" }, // where to redirect to after logout
AllowedScopes = new List<string>
{
IdentityServerConstants.StandardScopes.OpenId,
IdentityServerConstants.StandardScopes.Profile,
"api"
},
ClientSecrets =
{
new Secret("secret".Sha256())
},
RequireConsent = false,
AlwaysIncludeUserClaimsInIdToken = true
}
b)隐含方法
new Client
{
ClientName = "mvc Client",
ClientId = "mvc",
AllowedGrantTypes = {GrantType.ClientCredentials, GrantType.Implicit},
RedirectUris = { "http://localhost:5002/Account/Callback" }, // where to redirect to after login
PostLogoutRedirectUris = { "http://localhost:5002/signout-callback-oidc" }, // where to redirect to after logout
AllowedScopes = new List<string>
{
IdentityServerConstants.StandardScopes.OpenId,
IdentityServerConstants.StandardScopes.Profile,
"api"
},
ClientSecrets =
{
new Secret("secret".Sha256())
},
RequireConsent = false,
AlwaysIncludeUserClaimsInIdToken = true
}
a)使用 Microsoft.Owin.Security.OpenIdConnect ,其中未调用RedirectUri
Startup.cs
public void ConfigureAuthentication(IAppBuilder app)
{
app.UseCookieAuthentication(new CookieAuthenticationOptions
{
AuthenticationType = "Cookies"
});
app.UseOpenIdConnectAuthentication(new OpenIdConnectAuthenticationOptions
{
Authority = "http://localhost:5000", //ID Server
ClientId = "mvc",
ResponseType = "id_token code",
SignInAsAuthenticationType = "Cookies",
RedirectUri = "http://localhost:5002/Account/Callback", //URL of website
Scope = "openid profile",
});
}
b)使用第二种方法隐式
Startup.cs
public void ConfigureAuthentication(IAppBuilder app)
{
app.UseCookieAuthentication(new CookieAuthenticationOptions
{
AuthenticationType = "Cookies",
LoginPath = new PathString("/Account/Secure")
});
}
的AccountController
public class AccountController : BaseController
{
[AllowAnonymous]
public async Task<ActionResult> Secure()
{
return await StartAuthentication();
}
public async Task<ActionResult> Logout()
{
Authentication.SignOut("Cookies");
var disco = await DiscoveryClient.GetAsync(Constants.Authority);
return Redirect(disco.EndSessionEndpoint);
}
[AllowAnonymous]
private async Task<ActionResult> StartAuthentication()
{
// read discovery document to find authorize endpoint
var disco = await DiscoveryClient.GetAsync(Constants.Authority);
var authorizeUrl = new AuthorizeRequest(disco.AuthorizeEndpoint).CreateAuthorizeUrl(
clientId: "mvc",
responseType: "id_token",
scope: "openid profile",
redirectUri: "http://localhost:5002/Account/Callback",
state: "random_state",
nonce: "random_nonce",
responseMode: "form_post");
return Redirect(authorizeUrl);
}
public async Task<ActionResult> Callback()
{
var state = Request.Form["state"].ToString();
var idToken = Request.Form["id_token"].ToString();
if (!string.Equals(state, "random_state")) throw new Exception("invalid state");
var user = await ValidateIdentityToken(idToken, state);
var id = new ClaimsIdentity(user, "Cookies");
Authentication.SignIn(new AuthenticationProperties
{
IsPersistent = false
}, id);
//Here Loading other data for user from Database e.g SiteMap
// {...}
return Redirect("/");
}
private async Task<ClaimsPrincipal> ValidateIdentityToken(string idToken)
{
// working area
var token = new JwtSecurityToken(jwtEncodedString: idToken);
Console.WriteLine("email => " + token.Claims.First(c => c.Type == "email").Value);
//working area
//need to return user Claims from validated token. How to?
}
BaseController
[Authorize]
public abstract class BaseController : Controller
{
public IAuthenticationManager Authentication
{
get { return this.HttpContext.GetOwinContext().Authentication; }
}
// Methods that can be used in my other controllers.
}