IdentityServer / IdentityServer4

OpenID Connect and OAuth 2.0 Framework for ASP.NET Core
https://identityserver.io
Apache License 2.0
9.23k stars 4.02k forks source link

Connect to IdentityServer4 from WebForms App #78

Closed BlackMoon closed 8 years ago

BlackMoon commented 8 years ago

Dear, IdentityServer developers.

I start using IdentityServer to share logged users' info between web applications.

Our solutions' stack has plenty of ASPX WebForms-based applications and few projects based on asp.vnext. We also have plans to improve old projects using self-hosting owin architecture.

IdentityServer4 works good with new (asp.vnext) applications but another projects always get error: unauthorized_client The client application is not known or is not authorized.

So, please, could you show example of using IdentityServer4 authentication pipeline with ASPX Web Form (or just with owin-based applications)?

Here're source codes

Server (like in samples):

public class Startup
    {
        public void ConfigureServices(IServiceCollection services)
        {
            services.AddMvc();
        }

        public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory)
        {
            loggerFactory.AddConsole();
            loggerFactory.AddDebug();

            app.UseIISPlatformHandler();

            app.UseCors(policy =>
            {
                policy.WithOrigins("http://localhost:28895", "http://localhost:7017");
                policy.AllowAnyHeader();
                policy.AllowAnyMethod();
            });

            JwtSecurityTokenHandler.DefaultInboundClaimTypeMap.Clear();
            app.UseIdentityServerAuthentication(options =>
            {
                options.Authority = "http://localhost:22530/";
                options.ScopeName = "api1";
                options.ScopeSecret = "secret";

                options.AutomaticAuthenticate = true;
                options.AutomaticChallenge = true;
            });

            app.UseMvc();
        }

        // Entry point for the application.
        public static void Main(string[] args) => WebApplication.Run<Startup>(args);
    }

public class Clients
    {
        public static IEnumerable<Client> Get()
        {
            return new List<Client>{
               ///////////////////////////////////////////
                // MVC Implicit Flow Samples
                //////////////////////////////////////////
                new Client
                {
                    ClientId = "mvc_implicit",
                    ClientName = "WebApplication1",
                    ClientUri = "http://identityserver.io",

                    Flow = Flows.Implicit,
                    RedirectUris = new List<string>
                    {
                        "http://localhost:44077/signin-oidc"
                    },

                    AllowedScopes = new List<string>
                    {
                        StandardScopes.OpenId.Name,
                        StandardScopes.Profile.Name,
                        StandardScopes.Email.Name,
                        StandardScopes.Roles.Name,

                        "api1", "api2"
                    }
                }
            }
         }
       }

And client (web forms)

[assembly: OwinStartup(typeof(WebApplication1.Startup))]

namespace WebApplication1
{
    public class Startup
    {
        public void Configuration(IAppBuilder app)
        {
            app.UseCookieAuthentication(new CookieAuthenticationOptions()
            {
                AuthenticationType = "Cookies"
            });

            app.UseOpenIdConnectAuthentication(new OpenIdConnectAuthenticationOptions
            {
                Authority = "http://localhost:22530/",
                ClientId = "mvc_implicit",
                RedirectUri = "http://localhost:13270",
                ResponseType = "id_token token",

                SignInAsAuthenticationType = "Cookies"
            });

        }
    }
}

and in page

public partial class About : Page
    {
        protected void Page_Load(object sender, EventArgs e)
        {
            if (!Request.IsAuthenticated)
            {
                HttpContext.Current.GetOwinContext().Authentication.Challenge(
                    new AuthenticationProperties
                    {
                        RedirectUri = "/Contact.aspx"
                    },
                    OpenIdConnectAuthenticationDefaults.AuthenticationType);
            }
        }
    }

I'll be pleased to any example or link. Thanks.

brockallen commented 8 years ago

We have a web forms sample client using IdSvr3, but the client code would look the same regardless which one you're using. https://github.com/IdentityServer/IdentityServer3.Samples/tree/master/source/Clients/WebFormsClient

BlackMoon commented 8 years ago

Thanks, solved.

The reason of

unauthorized_client The client application is not known or is not authorized

was in RedirectUrl disparity between client on IdentityServers' list and RedirectUrl option in OpenIdConnectAuthenticationOptions.

jonas-stjernquist commented 7 years ago

Is the implicit flow the only option for a ASP.NET WebForms web application? Can hybrid flow be used?

We are currently migrating old web applications to use IdentityServer 4 in order to provide single-sign between with ASP.NET WebForms and ASP.NET Core MVC web applications.

leastprivilege commented 7 years ago

You can use hybrid flow of course. The question is rather how much custom code you have to write. Katana's OIDC middleware already does a lot for you (but not everything).

jonas-stjernquist commented 7 years ago

@leastprivilege OK I will research if implementing Hybrid flow instead of Implicit flow in our Webforms applications is useful for us, currently I don't have the full picture why chosing Hybrid instead of Implicit is preferred.

My guess (which probably isn't entire true) it that it's more secure to use Hybrid since the Implicit flow exposes id_token and access_token to the end-user browser, this is something that Hybrid flow doesn't do by default...

leastprivilege commented 7 years ago

yes - absolutely.

MazenDB commented 7 years ago

@BlackMoon Hello, I know I am asking a year later, but can you tell me how did you solve the issue and if possible share the code that you used for the client

BlackMoon commented 7 years ago

I store available clients in external jsonsettings file - clients.json

{ "ClientId": "eco.webforms", "ClientName": "ECO-Control", "RequireConsent": false, "AllowRememberConsent": false, "RedirectUris": [ "http://eco", "http://eco.aquilon.ru" ], "PostLogoutRedirectUris": [ "http://eco.aquilon.ru" ], "AllowedScopes": [ "openid", "connectionString" ] },

Custom scope - [ConnectionString]

Then override some dependencies

public IServiceProvider ConfigureServices(IServiceCollection services) { ...

region clients (from clients.json)

        builder.Services.AddSingleton<IEnumerable<Client>>(provider => provider.GetService<IOptions<List<Client>>>().Value);
        builder.Services.AddTransient<IClientStore, InMemoryClientStore>();
        builder.Services.AddTransient<ICorsPolicyService, InMemoryCorsPolicyService>();
        #endregion

        #region resources
        builder.AddInMemoryIdentityResources(accounts.Configuration.Resources.GetIdentityResources());
        #endregion

        #region users --> empty list
        builder.AddProfileService<Services.ProfileService>();
        builder.Services.AddSingleton(new List<InMemoryUser>());
        builder.Services.AddTransient<IResourceOwnerPasswordValidator, InMemoryUserResourceOwnerPasswordValidator>();
        #endregion

... }

Client WebForms App - OpenIdConfiguration config = ConfigurationManagerWrapper.GetSection("openid"); if (config != null) { options.AuthenticationType = config.SignInAsAuthenticationType; options.ExpireTimeSpan = TimeSpan.FromSeconds(config.ExpirationTime);

            if (!string.IsNullOrEmpty(config.CookieName))
                options.CookieName = config.CookieName;
        }

        app.UseCookieAuthentication(options);

        // если задан OpenId
        if (config != null)
        {
            JwtSecurityTokenHandler.InboundClaimTypeMap.Clear();

            app.UseOpenIdConnectAuthentication(new OpenIdConnectAuthenticationOptions
            {
                AuthenticationType = config.AuthenticationType,
                SignInAsAuthenticationType = config.SignInAsAuthenticationType,
                Authority = config.Authority,
                ClientId = config.ClientId,
                RedirectUri = config.RedirectUri,
                ResponseType = config.ResponceType,
                Scope = config.Scope,
                UseTokenLifetime = config.UseTokenLifetime,

                Notifications = new OpenIdConnectAuthenticationNotifications()
                {
                    RedirectToIdentityProvider = n =>
                    {
                        switch (n.ProtocolMessage.RequestType)
                        {
                            // if signing in, check domain binding
                            case OpenIdConnectRequestType.AuthenticationRequest:

                                Uri redirectUri = new Uri(n.ProtocolMessage.RedirectUri);
                                n.ProtocolMessage.RedirectUri =  n.ProtocolMessage.RedirectUri.Replace(redirectUri.Host, n.Request.Uri.Host);

                                break;

                            // if signing out, add the id_token_hint
                            case OpenIdConnectRequestType.LogoutRequest:

                                var idTokenHint = n.OwinContext.Authentication.User.FindFirst("id_token");
                                n.ProtocolMessage.IdTokenHint = idTokenHint?.Value;

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

                    SecurityTokenValidated = n =>
                    {
                        ClaimsIdentity ci = n.AuthenticationTicket.Identity;
                        ci.AddClaim(new Claim("id_token", n.ProtocolMessage.IdToken));

                       //

                        n.AuthenticationTicket = new AuthenticationTicket(
                            new ClaimsIdentity(ci.Claims, n.AuthenticationTicket.Identity.AuthenticationType, "name", "role"),
                            n.AuthenticationTicket.Properties);

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

            app.UseStageMarker(PipelineStage.Authenticate);`

`

MazenDB commented 7 years ago

Thanks for the reply, my problem was that the redirect Uri was not configured correctly at the server side. So silly!!

MazenDB commented 7 years ago

@BlackMoon If you can help with one more thing I'd be grateful. When you request to Login to the SSO, you get redirected from localhost/About to the SSO page. What part of the code is responsible for that ? I am using the sample provided at https://github.com/IdentityServer/IdentityServer3.Samples/tree/master/source/Clients/WebFormsClient

BlackMoon commented 7 years ago

This is default behaviour of ASPNet Cookie Authentication mechanism.

You can change default behaviour in app.UseCookieAuthentication middleware (overriding options/events)

BlackMoon commented 7 years ago

code path in

https://github.com/IdentityServer/IdentityServer3.Samples/blob/master/source/Clients/WebFormsClient/Startup.cs

Engineerumair commented 5 years ago

Hi, I am too late, but after reading all I have found that sample for webform is present in Identity Server 3 samples but I also found that Identity Server 3 isn't maintained any more.

can you please suggest how can I implement SSO in webforms

BlackMoon commented 5 years ago

Hi! It will take some time (1-2 days) to find out SSO implementation in WebForms

On Thu, 22 Nov 2018 at 16:20, Engineerumair notifications@github.com wrote:

Hi, I am too late, but after reading all I have found that sample for webform is present in Identity Server 3 samples but I also found that Identity Server 3 isn't maintained any more.

can you please suggest how can I implement SSO in webforms

— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub https://github.com/IdentityServer/IdentityServer4/issues/78#issuecomment-441028718, or mute the thread https://github.com/notifications/unsubscribe-auth/AFxVOPVQZHq5hXuniDW-2ki87BPN8yBAks5uxqSDgaJpZM4IOP8T .

-- С уважением, Романов Роман Валерьевич +7 (999) 897-61-74, +7 (917) 256-61-03 skype: black_m7

Engineerumair commented 5 years ago

@BlackMoon what do you mean by taking 1 - 2 days? I found webforms in Identity Server 3 but there isn't any client on webform on Identity Server 4. and please let me know that what kind of Identity Server 4 application is more suitable for existing old king of webform aspx pages?

BlackMoon commented 5 years ago

It was several years ago when I implemented sso in web forms, so I need time to find sources in archive backups

On Thu, 22 Nov 2018 at 19:32, Engineerumair notifications@github.com wrote:

@BlackMoon https://github.com/BlackMoon what do you mean by taking 1 - 2 days? I found webforms in Identity Server 3 but there isn't any client on webform on Identity Server 4. and please let me know that what kind of Identity Server 4 application is more suitable for existing old king of webform aspx pages?

— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub https://github.com/IdentityServer/IdentityServer4/issues/78#issuecomment-441079321, or mute the thread https://github.com/notifications/unsubscribe-auth/AFxVOPetlc3a8fU3EsZHViJRr7AJX8_7ks5uxtG2gaJpZM4IOP8T .

-- С уважением, Романов Роман Валерьевич +7 (999) 897-61-74, +7 (917) 256-61-03 skype: black_m7

Engineerumair commented 5 years ago

@BlackMoon can we use direct openID to implement SSO in webforms?

BlackMoon commented 5 years ago

As far as I remember, these steps are necessary:

  1. Convert Web form site to web forms application
  2. Add OWIN support to app
  3. In Startup, Configure(IAppBuilder) - put right-ordered OpenId middlewares
  4. In web.config - remove authorization- Forms

четверг, 22 ноября 2018 г. пользователь Engineerumair написал:

@BlackMoon https://github.com/BlackMoon can we use direct openID to implement SSO in webforms?

— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub https://github.com/IdentityServer/IdentityServer4/issues/78#issuecomment-441086631, or mute the thread https://github.com/notifications/unsubscribe-auth/AFxVOKKhcFaZ0Yo_oUAixf6I8f3RN0Qaks5uxtmdgaJpZM4IOP8T .

-- С уважением, Романов Роман Валерьевич +7 (999) 897-61-74, +7 (917) 256-61-03 skype: black_m7

Engineerumair commented 5 years ago

How to convert webform site into webform application? and can we use Identity Server 4 with webform client created for Identity server 3 and which one is best way to implement SSO 1 Identity Server 4 2 Direct using OpenID

BlackMoon commented 5 years ago

To convert pages and classes to use partial classes in a Web application project https://msdn.microsoft.com/en-us/library/aa983476.aspx

четверг, 22 ноября 2018 г. пользователь Engineerumair написал:

How to convert webform site into webform application?

— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub https://github.com/IdentityServer/IdentityServer4/issues/78#issuecomment-441109335, or mute the thread https://github.com/notifications/unsubscribe-auth/AFxVOCicTP_SOM0iMLh9nwWGy3BcF8guks5uxvzdgaJpZM4IOP8T .

-- С уважением, Романов Роман Валерьевич +7 (999) 897-61-74, +7 (917) 256-61-03 skype: black_m7

Engineerumair commented 5 years ago

@BlackMoon I don't need to convert my website into application because it is already an application I need to confirm that, can I directly use openID for Single Sign On rather than create an Identity server 4 application and hosting.

I want the existing application should use openID to have single sign on for google and facebook

BlackMoon commented 5 years ago

Fine. So your app can deal with OpenId

For Google/Facebook add into Configuration (IAppBuilder) -

app.UseOpenIdConnectAuthentication( new OpenIdConnectAuthenticationOptions { .......... } );

And set

None in web.config On Fri, 23 Nov 2018 at 16:39, Engineerumair wrote: > @BlackMoon I don't need to convert my > website into application because it is already an application > I need to confirm that, can I directly use openID for Single Sign On > rather than create an Identity server 4 application and hosting. > > I want the existing application should use openID to have single sign on > for google and facebook > > — > You are receiving this because you were mentioned. > Reply to this email directly, view it on GitHub > , > or mute the thread > > . > -- С уважением, Романов Роман Валерьевич +7 (999) 897-61-74, +7 (917) 256-61-03 skype: black_m7
BlackMoon commented 5 years ago

I used Identity Server to create custom SSO server inside my company’s intranet and for Oracle- based authentication

On Fri, 23 Nov 2018 at 20:17, Роман rrv.kazan@gmail.com wrote:

Fine. So your app can deal with OpenId

For Google/Facebook add into Configuration (IAppBuilder) -

app.UseOpenIdConnectAuthentication( new OpenIdConnectAuthenticationOptions { .......... } );

And set

None in web.config On Fri, 23 Nov 2018 at 16:39, Engineerumair wrote: > @BlackMoon I don't need to convert my > website into application because it is already an application > I need to confirm that, can I directly use openID for Single Sign On > rather than create an Identity server 4 application and hosting. > > I want the existing application should use openID to have single sign on > for google and facebook > > — > You are receiving this because you were mentioned. > Reply to this email directly, view it on GitHub > , > or mute the thread > > . > -- С уважением, Романов Роман Валерьевич +7 (999) 897-61-74, +7 (917) 256-61-03 skype: black_m7 -- С уважением, Романов Роман Валерьевич +7 (999) 897-61-74, +7 (917) 256-61-03 skype: black_m7
Engineerumair commented 5 years ago

If I don't need custom SSO then what is the better solution?

BlackMoon commented 5 years ago

Install Microsoft.Owin.Security Microsoft.Owin.Security.Cookies Microsoft.Owin.Security.Google Microsoft.Owin.Security.Facebook

Register your App on remote openId Server. You'll be provided back with proper URL, key and other options

Inject openId middlewares in request pipeline app.UseExternalSignInCookie app.UseGoogleAuthentication ....... and other necessary providers

пятница, 23 ноября 2018 г. пользователь Engineerumair написал:

If I don't need custom SSO then what is the better solution?

— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub https://github.com/IdentityServer/IdentityServer4/issues/78#issuecomment-441292825, or mute the thread https://github.com/notifications/unsubscribe-auth/AFxVOLPEs5_Yx61QeqIgdHFwTxD2hwPGks5uyDJIgaJpZM4IOP8T .

-- С уважением, Романов Роман Валерьевич +7 (999) 897-61-74, +7 (917) 256-61-03 skype: black_m7

Engineerumair commented 5 years ago

@BlackMoon Where can I find remote Identity Server

BlackMoon commented 5 years ago

Google guidelines- https://developers.google.com/identity/protocols/OpenIDConnect Facebook - https://developers.facebook.com/docs/facebook-login/

суббота, 24 ноября 2018 г. пользователь Engineerumair написал:

@BlackMoon https://github.com/BlackMoon Where can I find remote Identity Server

— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub https://github.com/IdentityServer/IdentityServer4/issues/78#issuecomment-441345813, or mute the thread https://github.com/notifications/unsubscribe-auth/AFxVOFH8-dcWelpE9u8tSQZXKClTONkFks5uyN7XgaJpZM4IOP8T .

-- С уважением, Романов Роман Валерьевич +7 (999) 897-61-74, +7 (917) 256-61-03 skype: black_m7

cemerson commented 4 years ago

I too am needing to figure out Webforms with IdentityServer so am struggling to get the IdentityServer3 sample project working. I finally got the solution down to only a couple remaining errors but this one I just can't figure out. Is "Item1" from Startup.cs line 63 deprecated? Screenshot below.

identity server 3 startupError Item1 20191105100720

lock[bot] commented 4 years ago

This thread has been automatically locked since there has not been any recent activity after it was closed. Please open a new issue for related bugs.