Douglas Anderson
Douglas Anderson

Reputation: 4700

Dynamically set OWIN redirect uri

I am using OWIN to connect up to O365 via the Microsoft Graph API in an ASP.NET MVC app. Everything is setup in Startup.Auth.cs including the Redirect Uri value which currently comes from the web.config. Authentication is working correctly.

As I am using wildcards in the App Registration, the redirect uri can be a variety of values and te user is able authenticate to O365 from any number of pages in the app. Once authenticated I'd like them to be brought back to the page they were just on but because the redirect uri is already set, they are brought back to that page.

How can I modify the redirect uri, elsewhere in my code, after the OWIN identity context has been created?

Below is a snippet of the startup code.

   public partial class Startup
    {
        public void ConfigureAuth(IAppBuilder app)
        {
            private static string redirectUri = ConfigurationManager.AppSettings["ida:RedirectUri"];
            ....                
            app.UseOpenIdConnectAuthentication(
               new OpenIdConnectAuthenticationOptions
               {

                   ClientId = appId,
                   Authority = "https://login.microsoftonline.com/organizations/v2.0",
                   PostLogoutRedirectUri = redirectUri,
                   RedirectUri = redirectUri,
                   Notifications = new OpenIdConnectAuthenticationNotifications
                   {
                       AuthorizationCodeReceived = async (context) =>
                       {

                           Dictionary<string, string> data = new Dictionary<string, string>();
                           data.Add("client_id", appId);
                           data.Add("client_secret", appSecret);
                           data.Add("code", code);
                           data.Add("grant_type", "authorization_code");
                           data.Add("redirect_uri", redirectUri);
                           ...

Upvotes: 8

Views: 5466

Answers (3)

Tekonline
Tekonline

Reputation: 113

For anyone coming here and wondering where they should put this, it still goes into your statup.auth.cs (or similar) file. Where you need to put it is here:

public void ConfigureAzureAuth(IAppBuilder app)
    {
        ServicePointManager.Expect100Continue = true;
        ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls
                                               | SecurityProtocolType.Tls11
                                               | SecurityProtocolType.Tls12
                                               | SecurityProtocolType.Ssl3;
        app.SetDefaultSignInAsAuthenticationType(CookieAuthenticationDefaults.AuthenticationType);

        app.UseCookieAuthentication(new CookieAuthenticationOptions());
        app.UseOpenIdConnectAuthentication(
        new OpenIdConnectAuthenticationOptions
        {
            // Sets the ClientId, authority, RedirectUri as obtained from web.config
            Caption = "Your site",
            AuthenticationType = "Your site",
            ClientId = clientId,
            Authority = authority,
            //MetadataAddress = "https://your auth url/.well-known/openid-configuration",
            RedirectUri = redirectUri,

            // PostLogoutRedirectUri is the page that users will be redirected to after sign-out. In this case, it is using the home page
            PostLogoutRedirectUri = "/",

            Scope = OpenIdConnectScope.OpenIdProfile,
            // ResponseType is set to request the code id_token - which contains basic information about the signed-in user
            ResponseType = OpenIdConnectResponseType.CodeIdToken,
            // OpenIdConnectAuthenticationNotifications configures OWIN to send notification of failed authentications to OnAuthenticationFailed method
            Notifications = new OpenIdConnectAuthenticationNotifications
            {

//These are like call backs, so they fire when the event happens.
                AuthenticationFailed = OnAuthenticationFailed,
                //We can tap into this notification to get the IOwinRequest object
                RedirectToIdentityProvider = (o) =>
                {
                    //here is where we set the redirect Uri based on the request we received.
                    o.ProtocolMessage.RedirectUri = DetermineRedirectUri(o.Request);
                    return Task.CompletedTask;
                },
                AuthorizationCodeReceived = (o) =>
                {
                    o.TokenEndpointRequest.RedirectUri = DetermineRedirectUri(o.Request);
                    return Task.CompletedTask;
                }
            },
            
        });


    }

You will also need the additional method that @brz included.

private string DetermineRedirectUri(IOwinRequest request)
    {
        return request.Scheme + System.Uri.SchemeDelimiter + request.Host + request.PathBase + "/Account/ExternalLoginCallback/";
    }

Upvotes: 1

brz
brz

Reputation: 1959

I wanted to dynamically determine the redirect_uri of the application and came up with this solution with the help of above answers and comments:

Notifications = new OpenIdConnectAuthenticationNotifications()
{
    RedirectToIdentityProvider = (o) =>
    {
        o.ProtocolMessage.RedirectUri = DetermineRedirectUri(o.Request);
        return Task.CompletedTask;
    },
    AuthorizationCodeReceived = (o) =>
    {
        o.TokenEndpointRequest.RedirectUri = DetermineRedirectUri(o.Request);
        return Task.CompletedTask;
    }
}

And the helper method:

private string DetermineRedirectUri(IOwinRequest request)
{
    return request.Scheme + System.Uri.SchemeDelimiter + request.Host + request.PathBase;
}

Upvotes: 3

CaPorter
CaPorter

Reputation: 511

I had a similar situation. I tied into RedirectToIdentityProvider, to modify the RedirectUri before sending the request to the identity provider. Something like the following

Notifications = new OpenIdConnectAuthenticationNotifications()
  { 
    RedirectToIdentityProvider = async (context) =>
      {
        context.ProtocolMessage.RedirectUri = "Whatever_You_Want_Here";
      }
  }

Upvotes: 11

Related Questions