如何在ASP Net 4.7 MVC应用程序中获取Identity Server 4的access_token

时间:2019-02-21 08:30:40

标签: c# asp.net identityserver4

我在ASP Net 4.7.2客户端应用程序中获取Identity Server 4的access_token来调用API时遇到一些问题。

在ASP .Net Core客户端中,我可以这样获得access_token:

public async Task<IActionResult> CallApi()
    {
        var accessToken = await HttpContext.GetTokenAsync("access_token");

        var client = new HttpClient();
        client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", accessToken);
        var content = await client.GetStringAsync("http://localhost:5001/identity");

        ViewBag.Json = JArray.Parse(content).ToString();
        return View("Json");
    }

很简单:

var accessToken = await HttpContext.GetTokenAsync("access_token");

但是如何在ASP Net 4.x客户端中获取access_token?

我的启动代码如下:

public class Startup
{
    public void Configuration(IAppBuilder app)
    {
        var authority = JwtSecurityTokenHandler.DefaultInboundClaimTypeMap = new Dictionary<string, string>();

        app.UseCookieAuthentication(new CookieAuthenticationOptions
        {
            AuthenticationType = "Cookies",
            CookieName = "CustomIdentityCookie"
        });

        app.UseOpenIdConnectAuthentication(new OpenIdConnectAuthenticationOptions
        {
            //AuthenticationType = "oidc",              
            Authority = "http://localhost:5000",
            RedirectUri = "http://localhost:57319/signin-oidc",
            PostLogoutRedirectUri = "http://localhost:57319/signout-callback-oidc",
            ClientId = "mvc472",
            ClientSecret = "secret",
            ResponseType = "code id_token",
            Scope = "api01 openid profile offline_access",

            // for debug
            RequireHttpsMetadata = false,

            UseTokenLifetime = false,
            SignInAsAuthenticationType = "Cookies"
        });
    }
}

1 个答案:

答案 0 :(得分:0)

我找到了解决方案。希望任何人都可以告诉我该解决方案是否可以。 我使用了来自IdentityServer3的解决方法,如下所示:IdentityServer 3 Mvc Client 我编辑了描述方法,并更新到Identity Server 4。

工作正常,但注销除外:从Identity Server注销后,我没有重定向到MVC App。我收到404错误,找不到/ signout-callback-oidc路由。

这里是新的Startup类:

public class Startup
{
    public void Configuration(IAppBuilder app)
    {
        //var authority = JwtSecurityTokenHandler.DefaultInboundClaimTypeMap = new Dictionary<string, string>();
        JwtSecurityTokenHandler.DefaultInboundClaimTypeMap = new Dictionary<string, string>();

        app.UseCookieAuthentication(new CookieAuthenticationOptions
        {
            AuthenticationType = "Cookies"
        });

        app.UseOpenIdConnectAuthentication(new OpenIdConnectAuthenticationOptions
        {
            AuthenticationType = "oidc",                
            Authority = "http://localhost:5000",
            RedirectUri = "http://localhost:57319/signin-oidc",
            PostLogoutRedirectUri = "http://localhost:57319/signout-callback-oidc",
            ClientId = "mvc472",
            ClientSecret = "secret",
            ResponseType = "code id_token",
            Scope = "api01 openid profile offline_access",

            // for debug
            RequireHttpsMetadata = false,

            UseTokenLifetime = false,
            SignInAsAuthenticationType = "Cookies",

            Notifications = new OpenIdConnectAuthenticationNotifications
            {
                AuthorizationCodeReceived = async n =>
                    {
                        var client = new HttpClient();
                        DiscoveryResponse disco = await client.GetDiscoveryDocumentAsync("http://localhost:5000");

                        var tokenResponse = await client.RequestAuthorizationCodeTokenAsync(new AuthorizationCodeTokenRequest
                        {
                            Address = disco.TokenEndpoint,
                            RedirectUri = "http://localhost:57319/signin-oidc",                             
                            ClientId = "mvc472",
                            ClientSecret = "secret",
                            Code = n.Code
                        });

                        var userInfoResponse = await client.GetUserInfoAsync(new UserInfoRequest
                        {
                            Address = disco.UserInfoEndpoint,
                            Token = tokenResponse.AccessToken
                        });

                        var id = new ClaimsIdentity(n.AuthenticationTicket.Identity.AuthenticationType);
                        id.AddClaims(userInfoResponse.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", tokenResponse.IdentityToken));
                        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
                            );

                    },

                // noch nicht getestet
                RedirectToIdentityProvider = n =>
                {
                    // if signing out, add the id_token_hint
                    if (n.ProtocolMessage.RequestType == OpenIdConnectRequestType.Logout)
                    {
                        var idTokenHint = n.OwinContext.Authentication.User.FindFirst("id_token");

                        if (idTokenHint != null)
                        {
                            n.ProtocolMessage.IdTokenHint = idTokenHint.Value;
                        }

                    }

                    return Task.FromResult(0);
                }
            }



        });
    }
}