IdentityServer 4 with an old WebForms site - identityserver3

I have an old webforms site which has many business critical users using microsoft.aspnet.identity 2.2
We are wanting to extend the site, but will be using a microservice type architecture to do this. We want to spin up new .NET core services, but they need to be able to connect to this legacy database full of users. And by this I mean be able to share logins (so the user doesn't need to login twice btn the various micro services)
Is the best way to standup a IdentityServer (on its own somewhere - maybe hosted in AWS) which connects to this database and then allow:
1) The webforms to authenticate to it
2) Future .net core micro services can auth to it?
Currently we have this for our app:
app.CreatePerOwinContext(ApplicationDbContext.Create);
app.CreatePerOwinContext<ApplicationUserManager>(ApplicationUserManager.Create);
app.CreatePerOwinContext<ApplicationSignInManager>(ApplicationSignInManager.Create);
// Enable the application to use a cookie to store information for the signed in user
// and to use a cookie to temporarily store information about a user logging in with a third party login provider
// Configure the sign in cookie
app.UseCookieAuthentication(new CookieAuthenticationOptions
{
AuthenticationType = DefaultAuthenticationTypes.ApplicationCookie,
LoginPath = new PathString("/Account/Login"),
SlidingExpiration = true,
CookieName = ".AspNet.SomeName"
});
// Use a cookie to temporarily store information about a user logging in with a third party login provider
app.UseExternalSignInCookie(DefaultAuthenticationTypes.ExternalCookie);h section

I would look at the IdentityServer4.Samples repo.
Looks like you are using OWIN, so you could easily adapt the MvcHybrid example:
https://github.com/IdentityServer/IdentityServer4.Samples/tree/release/Clients/src/MvcHybrid
If you are not using OWIN, then have a look at the HomeController in the MvcManual client. It can easily be ported over to a WebForms app.
https://github.com/IdentityServer/IdentityServer4.Samples/blob/release/Clients/src/MvcManual/Controllers/HomeController.cs

Related

Should I use keycloak or not?

I'm just starting a new project. The result will be an API server and a progressive web app. The API server is implemented with TypeScript and the NestJS framework, the client with Angular 6.
I've been flirting with keycloak for some time. Still, I'm not quite sure it's right for me yet. But I don't want to worry about things like token renewal anymore and find it sexy that Keycloak tells me how to create user roles.
What bothers me, is the following - integration. For my use case it is necessary that the login and all features like password reset and so on are part of my application. That means I want to create forms myself in order to be able to do this perfectly in my own design and not have a second translation process, etc. Keycloak themes are not an option. So is it possible to hide keycloak in such a way, or is it so complex that I shouldn't use Keyloak in the first place? Afaik there is already an issue with password resets - I can't request it from the user side but have to make an REST call to the admin endpoint - which is okay but not ideal since it requires me to do more server side logic ( and that is not why I want to use Keycloak).
In addition, Keycloak is too much about the GUI - which makes it difficult for me, especially during development. Because I also want to provide my team with a local instance of keycloak during development. But what is the concept to import the initial data into realms, apps and also users into Keycloak? I found some JSON imports - but so far only for realms and apps. Is there also a function to import a whole dumb?
So that my team builds on a pre-built setup and has a user for each role. A reproducible setup with Vagrant or Docker which contains the import of initial data - that would be the goal.
So in short my questions:
Is it still worth the effort using Keycloak if I want to use everything via the API or should I simply use Passport and JWT?
Can I have a reproducible setup during my development that includes realms, apps, users, user roles, etc?
So, the question asked few months ago, but I also faces with that question, and I want to answer on it.
I think that you don't need Keycloak, it is fairly enough for you to use OAuth2 and JWT.
Let's justify my answer:
You have just one client - Angular application. Keycloak useful, when you have many clients (web-js, mobile platforms) and you want to create and manage them dynamically. But, I think that, in your case, you create your client once without modification in the future.
Also, Keycloak very useful, when you have a lot of integration with third part systems (Google, Fb, Twitter and etc) because Keycloak has them out-of-box. Or you need to integrate with some SAML or LDAP provider.
You may use Keycloak, if you need some Identity and User management platform, and when you have complicated user access flow.
In the end, you could consider Keycloak, if you need SSO (Single Sign On) feature. Once logged-in to Keycloak, users don't have to login again to access a different application. But, by your description, you have just one application.
Keycloak offers features such as Single-Sign-On (SSO), Identity Brokering and Social Login, User Federation, Client Adapters, an Admin Console, and an Account Management Console.
It's an out of box solution for rapid security layer development of application.You could have single common security layer for multiple application .
You can implement you security mechanism without using keycloak.

liferay authentication from soap

I need integrate Liferay (version 6.2) with another service which stores information about users. Communication with service occurs through SOAP.
Is it possible use users from service to authenticate to Liferay?
Liferay integrates with external systems through LDAP already. If you use that interface, you're set. If you need a proprietary API to access user information, you will have some work in front of you.
It might be worth examining the SSO implementation and intercept newly authenticated users on this level: With the user's identity, create or update a Liferay user account on the fly through LIferay's API. To me this looks like the most promising approach from an effort/maintenance point of view, with the little information I have about your situation.
Alternatively you could batch-update all (Liferay-) user accounts from time to time, based on updates in your external system.
Let me see if I understand what need:
1- Step 1: User prompted with A login page.
2- Step 2: The credentials entered by the user are checked against a web service (could be any service)
3- Step 3: The user is either logged in or an auth error displayed to the user.
If that's what you need, then create an autologin hook. The code that call the webs service shall live in the autologin hook.
May seem intimidating, but it is trivial: likely liferay comes with a bunch of them: (take one of them as a template)
auto.login.hooks=com.liferay.portal.security.auth.CASAutoLogin,com.liferay.portal.security.auth.FacebookAutoLogin,com.liferay.portal.security.auth.NtlmAutoLogin,com.liferay.portal.security.auth.OpenIdAutoLogin,com.liferay.portal.security.auth.OpenSSOAutoLogin,com.liferay.portal.security.auth.RememberMeAutoLogin,com.liferay.portal.security.auth.SiteMinderAutoLogin

GWT Login: how to implement it?

I'm a bit confused about the making of a login service: I've seen plenty of tutorials, but still can't manage how to make a simple login service.
I don't know what tools I need to remember the navigation, and how to use them.
I could use:
public interface LoginServiceAsync {
boolean isAuthenticated(AsyncCallback<UserDTO> callback);
UserDTO authenticate(String email, String password, AsyncCallback<UserDTO> callback);
void logout(AsyncCallback<UserDTO> callback);
}
But where do I manage Cookies?
Pro Tip: if you don't fully understand how authentication should work, don't try to do it yourself.
IMO, the best way to do authentication is to just redirect to a login form and thus assume that when your app is loaded the user is authenticated (then you can use a JSP for example to pass user-specific values to your GWT app; see the guice-rf-activity archetype for an example). If your app has to be accessible to anonymous users, login would still just redirect to the login page. For a real-life example, have a look at how Google Groups behaves.
That way, you can delegate authentication to either some library that knows how to do it (e.g. Spring Security), or to some tool (e.g. standard servlets authentication, AppEngine-specific authentication)
GWT is just a tool that converts Java code into HTML and JavaScript. There is nothing special about authenticating users in GWT.
One option is to remember that a user is authenticated in a session, and then check the session every time a client makes an RPC call. The implementation depends on your web server. Google your web server and "sessions", and you will find plenty of details on how to do it.
I have also the same problem trying to find a login service. Finally we are using CAS Single Sign Out because we are working with Tomcat. In this case, users are directly logged in Tomcat server and not in GWT. Each user is configured to allow open a URL (GWT application) or not. For example, if the GWT application is hosted in htpp://myhost/GWTapp, it is possible to configure if a user can access to "/GWTapp" or not.
For me, the best benefit, it's that doesn't need to change a lot the GWT application with calls to server and so on. There is a GWT CAS client that makes all for you.

Securing REST API in Grails and Spring Security

I have split my Grails app into two apps - a customer facing web app and a separate app that hosts a REST api. I am doing this because I'm building an iOS app to go with my web app. My app uses Spring Security and I want to secure the REST api. I've surprisingly found very little information on the proper way to do this. Should I implement oauth with Spring Security, thus making my API app an oauth provider?
Any suggestions would be great.
Yes, I just did this for another application. You have to tell spring security to behave differently when the REST URLS are accessed.
Add this to your config.groovy
Now you will have two parts of your application that are authenticated in the following manner
a) Anything with /api ( assuming thats how you have your REST set up) in the URL, gets the basic authentication
b) Everything else , goes through the login page.
// making the application more secured by intercepting all URLs
grails.plugins.springsecurity.useBasicAuth = true
grails.plugins.springsecurity.basic.realmName = " REST API realm"
grails.plugins.springsecurity.securityConfigType = SecurityConfigType.InterceptUrlMap
//Exclude normal controllers from basic auth filter. Just the JSON API is included
grails.plugins.springsecurity.filterChain.chainMap = [
'/api/**': 'JOINED_FILTERS,-exceptionTranslationFilter',
'/**': 'JOINED_FILTERS,-basicAuthenticationFilter,-basicExceptionTranslationFilter'
]
I've been working during the last weeks on a plugin that covers exactly what you want to do:
http://grails.org/plugin/spring-security-rest
Have a look at it and let me know if you have any problem.

How do I log out of Facebook when using Azure's ACS?

Rule #6 of the Facebook developer policy says I must provide an explicit Log out link, but I'm unable to make it work.
My goal is to either sign my application out of Facebook, the user from the entire Facebook experience environment, or both. So far, I can't do any of these.
This may be complicated by the fact I'm using Azure ACS and am not using the typical FB APIs. Things I've tried include:
Attempt 1: Facebook OAuth Logout
"http://www.facebook.com/logout.php?api_key={0}&;session_key={1}";
// I don't know how to get the session key. I attempted the values stored in
// the claim "http://www.facebook.com/claims/AccessToken" but no luck
Attempt 2: ACS logout (undocumented?)
https://tlsadmin.accesscontrol.windows.net/v2/wsfederation?wa=wsignoutcleanup1.0
Neither of these approaches allow an alternate Facebook user to sign in. Any links would be appreciated.
Simplified Question
How do I get *.accescontrol.windows.net to redirect back to my website?
The December 2012 update of ACS includes support for federated single sign-out:
Using the WS-Federation protocol. Web applications that use ACS to
enable single sign-on (SSO) with identity providers using the
WS-Federation protocol can now take advantage of single sign out
capabilities. When a user signs out of a web application, ACS can
automatically sign the user out of the identity provider and out of
other relying party applications that use the same identity provider.
This feature is enable for WS-Federation identity providers, including
Active Directory Federation Services 2.0 and Windows Live ID
(Microsoft account). To enable single sign out, ACS performs the
following tasks for WS-Federation protocol endpoints:
ACS recognizes wsignoutcleanup1.0 messages from identity providers
and responds by sending wsignoutcleanup1.0 messages to relying party
applications.
ACS recognizes wsignout1.0 and wreply messages from relying party
applications and responds by sending wsignout1.0 messages to identity
providers and wsignoutcleanup1.0 messages to relying party
applications.
From the Code Sample: ASP.NET MVC 4 with Federated Sign-out, implement an Action like the following to sign out from ACS:
(Note that Windows Identity Foundation is now incorporated into .NET 4.5 Framework, that's why the new namespaces below)
using System.IdentityModel.Services;
using System.IdentityModel.Services.Configuration;
public ActionResult Logout()
{
// Load Identity Configuration
FederationConfiguration config = FederatedAuthentication.FederationConfiguration;
// Get wtrealm from WsFederationConfiguation Section
string wtrealm = config.WsFederationConfiguration.Realm;
string wreply;
// Construct wreply value from wtrealm (This will be the return URL to your app)
if (wtrealm.Last().Equals('/'))
{
wreply = wtrealm + "Logout";
}
else
{
wreply = wtrealm + "/Logout";
}
// Read the ACS Ws-Federation endpoint from web.Config
// something like "https://<your-namespace>.accesscontrol.windows.net/v2/wsfederation"
string wsFederationEndpoint = ConfigurationManager.AppSettings["ida:Issuer"];
SignOutRequestMessage signoutRequestMessage = new SignOutRequestMessage(new Uri(wsFederationEndpoint));
signoutRequestMessage.Parameters.Add("wreply", wreply);
signoutRequestMessage.Parameters.Add("wtrealm", wtrealm);
FederatedAuthentication.SessionAuthenticationModule.SignOut();
string signoutUrl = signoutRequestMessage.WriteQueryString();
return this.Redirect(signoutUrl);
}
As this post suggests: Azure AppFabric Access Control Service Log Off, you can create a custom log out button, and simply call the ederatedAuthentication.WSFederationAuthenticationModule.SignOut method on the click of the button. ACS then should handle the log out process for you.
Generally speaking there are two or three steps to federated sign out - locally you need to remove the forms auth cookie if one was used as well as the FIM cookie, this will sign out from the local application.
You then need to issue wasignoutcleanup10 request to the STS used, which would sign you out from the STS itself and, in theory, shoud issue a wasignoutcleanup1.0 request (or equivalent) to all the other IPs that were involved in the process (the STS should keep track of which IPs were contacted for each request)
I built such scenario once using Windows Identity Foundation which has the components needed, but it did require some development to keep track of the all the IPs and issue the calls.
I suspect that the ACS currently does not support this behaviour meaning that a user will have to close the browser to fully sign-out from all the applications.