Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
1.1k views
in Technique[技术] by (71.8m points)

asp.net - OWIN openid connect external login doesn't execute specified callback url

I am using owin openid connect authentication where the authentication provider is hosted on a separate domain. The authentication process works nicely. I am able to view restricted pages upon successful login at the identity server.

But I want the external identity server to return back to "account/SignInCallback" controller action so that I can execute a few lines of code relevant for the member's account. In the browser's network activity it shows me "302 Found" for the "account/SignInCallback" but it doesn't hit the breakpoints attached to it. It directly goes to the request initiating url e.g. "account/Dashboard".

Is there an way I can force the system to return back to the specific url after login, even though requesting url was different?

public class AccountController : BaseController
{
    public AccountController() : base()
    {
    }

    [Authorize]
    public ActionResult Dashboard()
    {
        return View();
    }

    [HttpPost]
    [AllowAnonymous]
    public ActionResult SignInCallback()
    {
        if (User.Identity.IsAuthenticated)
        {
            // Read claims and execute member specific codes
        }
        return View();
    }

    [AllowAnonymous]
    public ActionResult Unauthorized()
    {
        return View();
    }
}

The startup class is below:

public sealed class Startup
{   
    public void Configuration(IAppBuilder app)
    {
        string ClientCallbackUri = @"https://client.local/account/SignInCallback";
        string IdServBaseUri = @"https://idm.website.com/core";
        string TokenEndpoint = @"https://idm.website.com/core/connect/token";
        string UserInfoEndpoint = @"https://idm.website.com/core/connect/userinfo";
        string ClientId = @"WebPortalDemo";
        string ClientSecret = @"aG90apW2+DbX1wVnwwLD+eu17g3vPRIg7p1OnzT14TE=";

        JwtSecurityTokenHandler.InboundClaimTypeMap = new Dictionary<string, string>();

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

        app.UseOpenIdConnectAuthentication(new OpenIdConnectAuthenticationOptions
        {
            ClientId = ClientId,
            Authority = IdServBaseUri,
            RedirectUri = ClientCallbackUri,
            PostLogoutRedirectUri = ClientUri,
            ResponseType = "code id_token token",
            Scope = "openid profile roles",
            TokenValidationParameters = new TokenValidationParameters
            {
                NameClaimType = "name",
                RoleClaimType = "role"
            },
            SignInAsAuthenticationType = "Cookies",

            Notifications = new OpenIdConnectAuthenticationNotifications
            {
                AuthorizationCodeReceived = async n =>
                {
                    // use the code to get the access and refresh token
                    var tokenClient = new TokenClient(
                        TokenEndpoint,
                        ClientId,
                        ClientSecret);

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

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

                    // use the access token to retrieve claims from userinfo
                    var userInfoClient = new UserInfoClient(UserInfoEndpoint);

                    var userInfoResponse = await userInfoClient.GetAsync(tokenResponse.AccessToken);

                    // create new identity
                    var id = new ClaimsIdentity(n.AuthenticationTicket.Identity.AuthenticationType);
                    //id.AddClaims(userInfoResponse.GetClaimsIdentity().Claims);
                    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", 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);
                }
            }
        });
    }
}
See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

It looks all you need is to set

n.AuthenticationTicket.Properties.RedirectUri = n.RedirectUri;

in your AuthorizationCodeReceived delegate


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...