4

i have a MVC app with authorization managed by identityserver. When i access first time to my web, it is redirect to identityserver loggin page and after i am redirected to my web again.

My problem is, if i logout of identityserver, when i access again to my web (with identityserver authorization) i am redirected to identityserver but login is done automatically alowing me access to my web without put user/pass in identityserver.

I supose it is because cookie is still alive in client (if i delete manually in my browser all cookies then user/pass is required).

How can i disable auto login (force that user/pass is always required) ?

my startup client configuration is like:

 app.UseCookieAuthentication(new CookieAuthenticationOptions
        {
            LoginPath = new PathString("/Home/Logged/"),
            AuthenticationType = "Cookies",
            ExpireTimeSpan = TimeSpan.FromDays(2),
            SlidingExpiration = true,
            CookieName = ".AspNet.MyApp"

        });


        app.UseOpenIdConnectAuthentication(new OpenIdConnectAuthenticationOptions
        {
            ClientId = "MyApp",
            Authority = IS_URL,
            RedirectUri = localHostURL + "/Home/Logged/",
            PostLogoutRedirectUri = localHostURL + "/Account/Login/",
            ResponseType = "code id_token token", 
            Scope = "openid profile read write sampleApi",
            SignInAsAuthenticationType = "Cookies",

            UseTokenLifetime = true,

            Notifications = new OpenIdConnectAuthenticationNotifications
            {
                SecurityTokenValidated = async n =>
                {
                    var nid = new ClaimsIdentity(
                        n.AuthenticationTicket.Identity.AuthenticationType,
                        "given_name",
                        "role");

                    // get userinfo data
                    var userInfoClient = new UserInfoClient(
                        new System.Uri(n.Options.Authority + "/connect/userinfo"),
                        n.ProtocolMessage.AccessToken);

                    var userInfo = await userInfoClient.GetAsync();
                    userInfo.Claims.ToList().ForEach(ui => nid.AddClaim(new Claim(ui.Item1, ui.Item2)));

                    //keep the id_token for logout

                   nid.AddClaim(new Claim("id_token", n.ProtocolMessage.IdToken));

                   // add access token for sample API
                   nid.AddClaim(new Claim("access_token", n.ProtocolMessage.AccessToken));

                    // keep track of access token expiration
                    nid.AddClaim(new Claim("expires_at", TimeSpan.FromDays(2).ToString()));

                    // add some other app specific claim
                    nid.AddClaim(new Claim("app_specific", "some data"));

                    n.AuthenticationTicket = new AuthenticationTicket(
                        nid,
                        n.AuthenticationTicket.Properties);
                },
                RedirectToIdentityProvider = n =>
                {
                    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);
                }
            }
        });

Thanks in advance!

Sem
  • 73
  • 1
  • 6

4 Answers4

1

On login requests/redirects to idsrv, set the prompt parameter to login.

OnRedirectToIdentityProvider = n =>
{

    if (n.ProtocolMessage.RequestType == OpenIdConnectRequestType.Authentication)
    {    
        n.ProtocolMessage.Prompt = "login";
    }

    return Task.FromResult(0);
}

IdSrv docs (see prompt)

prompt (optional)

login the login UI will be shown, even if the user is already signed-in and has a valid session.

OpenId Connect spec around /authorize requests

prompt=login

The Authorization Server SHOULD prompt the End-User for reauthentication. If it cannot reauthenticate the End-User, it MUST return an error, typically login_required.

Ignas
  • 4,092
  • 17
  • 28
John Korsnes
  • 2,277
  • 2
  • 20
  • 31
1

To log out from identityserver you need to redirect to the end session endpoint.

Typically /connect/endsession. Only this way the authentication session cookie can be cleared.

See the spec: https://openid.net/specs/openid-connect-session-1_0.html#RPLogout

leastprivilege
  • 18,196
  • 1
  • 34
  • 50
0

I had similar requirement. Not the most elegant way, but I solved it by reducing the cookie expiration to 10 seconds and turning slidingexpiration off. Here the edge case is if the relying party comes back within 10 seconds, login prompt is bypassed.

Amey
  • 1,216
  • 18
  • 28
0

I battled with this for a confidentialclient app using MVC (Not Core). I eventually resolved this as follows: Under Notifications in the ConfigureAuth(IAppBuilder app) add a reference to a new task: RedirectToIdentityProvider = OnRedirectToIdentityProvider, Then add the task:

private Task OnRedirectToIdentityProvider(RedirectToIdentityProviderNotification
<OpenIdConnectMessage, OpenIdConnectAuthenticationOptions> notification) 
     {             
         // Forces the user to login. 
         if (notification.ProtocolMessage.Prompt == null) 
         { 
             notification.ProtocolMessage.Prompt = "login";                 
         } 
         return Task.FromResult(0); 
     }
Philip
  • 1
  • 1
  • 4