ADFS Когда и как использовать токен refre sh [UseOpenIdConnectAuthentication - ASP. NET MVC5] - PullRequest
0 голосов
/ 07 апреля 2020

В Startup.Auth.cs в уведомлении AuthorizationCodeReceived я получаю и accessToken (время жизни 1 час), и refreshToken (24 часа). Проблема в том, что я не знаю, когда запрашивать новый токен доступа и как его запрашивать. Пример полного кода был бы очень полезен, поскольку я новичок, относительно adfs и owin.

Пользователи, в некоторый момент, перенаправляются на adfs и затем возвращаются на веб-сайт, но они теряют свои сеанс и ошибки.

вот полный дамп кода:

public partial class Startup
{
    private readonly string authority = ConfigurationManager.AppSettings["auth:Authority"];
    private readonly string clientId = ConfigurationManager.AppSettings["auth:ClientId"];
    private readonly string clientSecret = ConfigurationManager.AppSettings["auth:ClientSecret"];
    private readonly string metadataAddress = ConfigurationManager.AppSettings["auth:MetadataAddress"];

    private readonly string postLogoutRedirectUri = ConfigurationManager.AppSettings["auth:PostLogoutRedirectUri"];
    private readonly string redirectUri = ConfigurationManager.AppSettings["auth:RedirectUri"];
    private readonly string tokenEndpoint = ConfigurationManager.AppSettings["auth:TokenEndpoint"];

    public void ConfigureAuth(IAppBuilder app)
    {
        app.UseCookieAuthentication(new CookieAuthenticationOptions
        {
            AuthenticationType = "Cookies",
            CookieHttpOnly = true
        });

        app.UseOpenIdConnectAuthentication(new OpenIdConnectAuthenticationOptions
        {
            Authority = this.authority,
            ClientId = this.clientId,
            ClientSecret = this.clientSecret,
            MetadataAddress = this.metadataAddress,
            RedirectUri = this.redirectUri,
            ResponseType = "code id_token",
            Scope = "offline_access openid profile customscope",
            RequireHttpsMetadata = false, //bool.Parse(ConfigurationManager.AppSettings["IsProduction"]),
            PostLogoutRedirectUri = this.postLogoutRedirectUri,
            SignInAsAuthenticationType = "Cookies",
            AuthenticationMode = AuthenticationMode.Active,
            UseTokenLifetime = false,

            Notifications = new OpenIdConnectAuthenticationNotifications
            {
                AuthorizationCodeReceived = async n =>
                {
                    // use the code to get the access and refresh token
                    var tokenClient = new TokenClient(
                        this.tokenEndpoint,
                        this.clientId,
                        this.clientSecret);

                    var tokenResponse = await tokenClient.RequestAuthorizationCodeAsync(n.Code, n.RedirectUri);

                    if (tokenResponse.IsError)
                    {
                        throw new Exception(tokenResponse.Error);
                    }

                    var handler = new JwtSecurityTokenHandler();
                    var identityToken = handler.ReadJwtToken(tokenResponse.IdentityToken);
                    var upn = identityToken.Claims.ToList().FirstOrDefault(c => c.Type == "upn")?.Value;

                    var localUser = new UserReader().GetByUpn(upn);

                    // mandatory for logout user
                    var id = new ClaimsIdentity(n.AuthenticationTicket.Identity.AuthenticationType);

                    if (localUser?.Id != null)
                    {
                        id.AddClaim(new Claim(ClaimTypes.Upn, localUser.Upn));
                        id.AddClaim(new Claim("Id", localUser.Id.ToString()));
                        id.AddClaim(new Claim("Name", localUser.Name));
                        id.AddClaim(new Claim("RoleId", localUser.Role.Id.ToString()));
                        id.AddClaim(new Claim("RoleName", localUser.Role.Name));
                        id.AddClaim(new Claim("IsOffice", localUser.Role.IsOffice.ToString()));
                        id.AddClaim(new Claim("IsInvestment", localUser.Role.IsInvestment.ToString()));
                    }

                    id.AddClaim(new Claim("identityToken", tokenResponse.IdentityToken));
                    id.AddClaim(new Claim("access_token", tokenResponse.AccessToken));
                    id.AddClaim(new Claim("expires_at",
                        DateTime.UtcNow.AddSeconds(tokenResponse.ExpiresIn).ToString(CultureInfo.InvariantCulture)));
                    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 (n.ProtocolMessage.RequestType == OpenIdConnectRequestType.Logout)
                    {
                        // valoarea idTokenHint nu persistă și fără, nu face redirect către login, imediat după log-out

                        var idTokenHint = n.OwinContext.Authentication.User.FindFirst("id_token");

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

                    n.ProtocolMessage.PostLogoutRedirectUri = this.postLogoutRedirectUri;
                    return Task.FromResult(0);
                },
                AuthenticationFailed = (context) =>
                {
                    if (context.Exception.Message.Contains("IDX21323") || context.Exception.Message.Contains("IDX10311"))
                    {
                        // Cateodata da eroare ca nu gaseste nonce cookie, si atunci trebuie relogat la ADFS
                        context.HandleResponse();
                        context.OwinContext.Authentication.Challenge();
                    }


                    return Task.FromResult(0);
                }
            }
        });
    }
}

1 Ответ

0 голосов
/ 07 апреля 2020

Чтобы использовать токен refre sh, выполните запрос POST к конечной точке токена ADFS с помощью:

grant_type = refresh_token

Включите токен refre sh, а также клиента учетные данные.

например,

https://ADFS арендатор / oauth / токен? grant_type = refresh_token & client_id = CLIENT_ID & client_secret = CLIENT_SECRET & refresh_token = REFRESH_TOKEN

это вещь MSAL Библиотека должна обработать это для вас.

Вам не нужно писать код.

Посмотрите примеры кода здесь в ADAL / MSAL.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...