Update ClaimsPrincipal with OpenIDConnect Middleware, MVC Client, Cookies

Is there a standard way to ask the MVC client to use ID4 OIDC middleware to update ClaimsPrincipal when using cookies? It would be nice to ask the middleware to update the ClaimsPrincipal, but I don't think this functionality exists.

The code below works, however the example below does not use a nonce, so I'm not sure if it's safe. I'm not sure how the middleware creates the nonce.

Does anyone have an example of how to properly update ClaimsPrincipal in an MVC client application using cookies with ID4 OIDC middleware?

Check id token and return ClaimsPrincipal from id

private ClaimsPrincipal ValidateIdentityToken(string idToken, DiscoveryResponse disco  )
    {


        var keys = new List<SecurityKey>();
        foreach (var webKey in disco.KeySet.Keys)
        {
            var e = Base64Url.Decode(webKey.E);
            var n = Base64Url.Decode(webKey.N);

            var key = new RsaSecurityKey(new RSAParameters { Exponent = e, Modulus = n });
            key.KeyId = webKey.Kid;

            keys.Add(key);
        }

        var parameters = new TokenValidationParameters
        {
            ValidIssuer = disco.TryGetString(OidcConstants.Discovery.Issuer),
            ValidAudience = "mvc.hybrid",
            IssuerSigningKeys = keys,

            NameClaimType = JwtClaimTypes.Name,
            RoleClaimType = JwtClaimTypes.Role
        };

        var handler = new JwtSecurityTokenHandler();
        handler.InboundClaimTypeMap.Clear();

        SecurityToken token;
        var user = handler.ValidateToken(idToken, parameters, out token);

        //var nonce = user.FindFirst("nonce")?.Value ?? "";
        //if (!string.Equals(nonce, "random_nonce")) throw new Exception("invalid nonce");
       //nonce is always ""
        return user;
    }

      

Check the cookie expiration date. Use refresh token to refresh ID and access token. Use the above validation to return a ClaimsPrincipal

 public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory)
    {


        app.UseCookieAuthentication(new CookieAuthenticationOptions
        {
            AuthenticationScheme = "Cookies",
            AutomaticAuthenticate = true,
            ExpireTimeSpan = TimeSpan.FromMinutes(60),

            Events = new CookieAuthenticationEvents()
            {
                OnValidatePrincipal = async cookiecontext =>
                {
                    if (cookiecontext.Properties.Items.ContainsKey(".Token.expires_at"))
                    {
                        var expire = DateTime.Parse(cookiecontext.Properties.Items[".Token.expires_at"]);
                        if (expire <= DateTime.Now.AddMinutes(-5) || DateTime.Now > expire)
                        {
                            var disco = await DiscoveryClient.GetAsync("http://localhost:5000");
                            if (disco.IsError) throw new Exception(disco.Error);


                            var refreshToken = cookiecontext.Properties.Items[".Token.refresh_token"];
                            var tokenClient = new TokenClient(disco.TokenEndpoint,
                                "mvc.hybrid",
                                "secret");
                            var response = await tokenClient.RequestRefreshTokenAsync(refreshToken);
                            if (!response.IsError)
                            {
                                cookiecontext.Properties.Items[".Token.access_token"] = response.AccessToken;
                                cookiecontext.Properties.Items[".Token.refresh_token"] = response.RefreshToken;
                                cookiecontext.Properties.Items[".Token.expires_at"] = DateTime.Now.AddSeconds((int)response.ExpiresIn).ToString();
                                cookiecontext.Properties.Items["NextAccessTokenRefresh"] = DateTime.Now.AddMinutes(5).ToString();

                                var _Princ = ValidateIdentityToken(response.IdentityToken, disco);

                                cookiecontext.ReplacePrincipal(_Princ);                                    

                                cookiecontext.ShouldRenew = true;

                            }
                            else
                            {
                                cookiecontext.RejectPrincipal();
                            }
                        }
                    }
                }
            }
        });

      

Wired ID4 middleware

 JwtSecurityTokenHandler.DefaultInboundClaimTypeMap.Clear();

        app.UseOpenIdConnectAuthentication(new OpenIdConnectOptions
        {
            AuthenticationScheme = "oidc",
            SignInScheme = "Cookies",

            Authority = "http://localhost:5000", 
            RequireHttpsMetadata = false,

            ClientId = "mvc.hybrid",
            ClientSecret = "secret",


            ResponseType = "code id_token",
            Scope = { "openid", "profile", "email", "api1", "offline_access", "role" },
            GetClaimsFromUserInfoEndpoint = true,
            Events = new OpenIdConnectEvents()
            {
                OnTicketReceived = notification =>
                {
                    notification.Response.Cookies.Append("NextAccessTokenRefresh", DateTime.Now.AddMinutes(5).ToString());
                    return Task.FromResult(0);
                }
            },

            SaveTokens = true,

            TokenValidationParameters = new Microsoft.IdentityModel.Tokens.TokenValidationParameters
            {
                NameClaimType = JwtClaimTypes.Name,
                RoleClaimType = JwtClaimTypes.Role,
            }
        });


    }

      

+3
identityserver4


source to share


No one has answered this question yet

Check out similar questions:

ten
IdentityServer4 - redirect to MVC client after logout
3
Cookie and Token Middleware in IdentityServer
2
What should the LogoutUri need for a WebForms client using OpenIdConnect authentication?
2
How to align client and IdentityServer cookies
1
MVC client does not redirect to IdentityServer4 identity UI
1
OpenIdConnect Middleware Tool Adds Request Scope to Request
1
SaveTokens = true stupid in OpenIdConnect middleware?
0
Cannot get username in MVC client application.
0
IdentityServer with MVC API and Angular Client
0
Refresh IdentityServer cookie when client cookie slides



All Articles
Loading...
X
Show
Funny
Dev
Pics