In an enterprise applications, how to seamless sign in to application without login page by reading the windows AD credentials using Spring boot and React.
Ex: if i login to my desktop using organisation AD credentials, can my spring boot react application read that and auto sign in with out login popup?
Yes that is possible. There are few necessary steps you need to perform.
Whenever user hits the application url, check Authorization header and verify if the kerberos ticket is present.
If the ticket is not present, respond with http header WWW-Authenticate and value Negotiate. Make sure the http status should be SC_UNAUTHORIZED(401). (note: usually spring kerberos filters should do it for you. If you are not using Spring kerberos filters, then you have to do this negotiation manually as stated above.
When browser receives this response, it understands that the application requires kerberos token. To ensure that the browser sends the kerberos token, trust the application url in browser settings. Check this link for exact steps.
Once browser sends the kerberos token, use Spring Secuiryt Kerberos libraries to accept the token and extract user principal out of it.
Related
My application is mainly based on spring boot micro services. Currently it uses OAuth with password grant_type which is deprecated in the latest spring security authorization server release. For receiving JWT token, it stores client id and client secret in React JS frontend which is not secure and not recommended. Users need to register to access certain resources and application maintains login credentials in mysql DB
I am trying to upgrade spring security and want 'account service' to act as authorization server to issue JWT tokens.
Am I correct in my understanding that I need to use authorization_code grand type with PKCE?
If I use PKCE then I do not need users to provide passwords while registering, is that correct? Storing only username/email should suffice because users just need to pass client ID and code_challenge to get authorization code?
Am I correct in my understanding that I need to use authorization_code grand type with PKCE?
The newest version of Spring Security mode introduces a new project for the Authorization server in the scope of Spring Security:
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-oauth2-authorization-server</artifactId>
<version>0.3.1</version>
</dependency>
The authorization server from spring implements OAuth2.1 where as you mentioned, both PASSWORD and IMPLICIT grant types were removed comparing it to OAuth 2.0.
Gran types supported in OAuth 2.1: 1
Authorization code + PKCE
client credentials
device grant type
OAuth 2.1 provide authorization code + PKCE grant type but it's a little bit different from the previous.
"The key difference between the PKCE flow and the standard
Authorization Code flow is users aren’t required to provide a
client_secret. (...) In place of the client_secret, the client app
creates a unique string value, code_verifier, which it hashes and
encodes as a code_challenge. When the client app initiates the first
part of the Authorization Code flow, it sends a hashed
code_challenge."
2
That type of grant type is recommended for SPA application so if you want to use the newest version of spring security you need to use it, because e.g. client credentials are reserved for machine-to-machine communication when one service needs to communicate with another service without of user's knowledge.
If I use PKCE then I do not need users to provide passwords while registering, is that correct?
Users need to authenticate themselves and that's a part of this grant-type flow.
Storing only username/email should suffice because users just need to pass client ID and code_challenge to get an authorization code?
ClientID and generated code_challenge (should be generated by the client) is something that identifies the client not the resource owner, so user while authorized shouldn't provide this type of info.
Authorizing client request
With OAuth2, clients (your React app) must authorize requests to protected resources, that is provide an access-token as Bearer Authorization header.
When acting on behalf of a user, clients should use authorization-code flow (with PKCE) to fetch such an access-token from authorization-server.
Also, use an OAuth2 client library in your React app. It will help you to:
redirect users to authorization-server
handle redirection back from authorisation-server with authorization code
exchange authorization code for tokens (access, refresh and ID)
Some libs even handle:
access token silent refresh before it expires
request Authorization to configured routes (add access token as header)
automatically trigger login when a user tries to access protected parts of the app.
I have not enough experience with React to recommend a specific lib, but you can search with "OpenID", "OIDC" or even "OAuth2" keywords
Configuring spring REST APIs
REST APIs secured with OAuth2 are "resource-servers". You can use spring-boot-starter-oauth2-resource-server directly as done in the first of those tutorials, but it is quite some Java conf.
Instead, you can use one of the spring-boot starters from the same repo. They are thin wrappers around spring-boot-starter-oauth2-resource-server with sensible defaults and most security conf from properties:
<dependency>
<groupId>com.c4-soft.springaddons</groupId>
<!-- replace "webmvc" with "webflux" if your app is a servlet -->
<!-- replace "jwt" with "introspecting" to use token introspection instead of JWT decoding -->
<artifactId>spring-addons-webmvc-jwt-resource-server</artifactId>
<!-- this version is to be used with spring-boot 3.0.0-RC2, use 5.x for spring-boot 2.6.x or before -->
<version>6.0.5</version>
</dependency>
#EnableMethodSecurity
public static class WebSecurityConfig { }
com.c4-soft.springaddons.security.issuers[0].location=https://localhost:8443/realms/master
com.c4-soft.springaddons.security.issuers[0].authorities.claims=realm_access.roles,ressource_access.some-client.roles
com.c4-soft.springaddons.security.cors[0].path=/some-api
Configuring the gateway
Basically, nothing to do in regard to authentication and OAuth2: inbound requests to secured resources should have an authorization header already and resource-servers will respond with 401 if authentication is missing or invalid (expired, wrong issuer, ...) or 403 if access is denied (valid identity but not allowed to access that resource)
authorization-server
Any OAuth2 authorization-server would do, but you might choose an OIDC implementation.
Authorization-server will handle users registration, login and logout. It will issue access, refresh and ID tokens, using mainly:
authorization-code flow for clients acting on behalf of a user
client-credential flow for trusted programmatic client acting in their own name (not on behalf of a user)
refresh-token: if offline_access scope is requested when authenticating (with any flow), a refresh-token is returned in addition to access-token and can be used to silently get a new access-token when current expires (or just before it does)
You can use Spring authorization-server framework to build your own authorization-server, but could also prefer to pick one "off the shelf": there are plenty out there with a lot of features implemented
connect to LDAP and "social" identity providers (Google, Facebook, Github, etc.)
enhance security with multi-factor authentication
provide with admin UI for stuff like user roles or tokens content
...
And this either on premise (Keycloak is a quite popular sample) or SaaS (like Auth0 and many others: almost any cloud provider has its own solution).
I have been looking into using an identity provider (IDP) to provide user authentication for a Windows Forms client. The user credentials will be hosted by Auth0. After creating a trial account with Auth0 I have downloaded a sample C# Windows Forms client application that can be used to authenticate to the Auth0 IDP using OpenID Connect ("OIDC"). The WinForms sample application pops up a web browser component, displays the Auth0 login screen, I login to the Auth0 IDP (having setup some test credentials in Auth0) and the WinForms application then is sent an authentication token. All well and good, and if I try to login a second time I no longer need to enter my credentials.
However... the company that I will be fetching authentication data from in production would like to use SAML. Is there any way to do this? Based on what I have read, SAML needs a "Service Provider" that will receive credentials from the IDP. The Service Provider is (typically?) a web site. That does not seem to match very well with what I am trying to do (authenticate a windows client). Is there any way of using SAML to do essentially what I have done using OIDC (fetch authentication information for a user from an IDP)? Would I need to develop a separate Service Provider component for this?
Sounds like what you've done so far is fine architecturally:
A modern desktop app following OIDC standards
This puts you in a good position architecturally, where:
Your app gets tokens from Auth0 using OIDC
Auth0 can reach out and do federated authentication with other standards based identity providers, which could be SAML, OIDC, WS-Federation or anything else
This can be done without changing any code in your app - and your app does not need to understand SAML
Feels like you need to set up a federated connection from Auth0 to the SAML Service Provider, and most commonly this involves these steps:
You give the partner your Entity Id and Response URL, to post tokens to
They give you am Entity Id, Public Key Certificate and request URL
You configure rules around account linking, so that users can be matched between their system and yours
There are prerequisites though, and the external identity provider needs to be SAML 2.0 compliant. My Federated Logins Article may help you to understand the general concepts, though I do not drill into SAML details here.
I have a web app developed using Create-react-app
I host it on IIS, the IIS only response to load the app, there is no server side logic on it (no Express or any other web server)
The app is using a RESTful API on the same IIS, it is out of my control (I cannot make change).
Now one of my client request to add SAML SSO to our app.
I would like to know:
in normal situation, which one is the Service Provider? My IIS Web server? or the API service?
For my case, I cannot implement SAML to API service, my web service only used to load my app without server side logic, how can I implement SAML?
Could any one give me some React implement SAML SSO tutorial or article for reference?
Thanks for any help, any information or suggestion are welcome!
in normal situation, which one is the Service Provider? My IIS Web server? or the API service?
I assume the client wants to authenticate the users using their internal IdP. So your application is the SP. But you will have to define different token service (details below).
With SPA (a single-page-applications) I see the problem, in SAML the user is redirected or posted away from the SAML request and SAML response.
I have a login page to enter id/pw, post them to API server Login endpoint to authenticate and get back a JWT token. After that we use that token in API calls for authentication
The API services are using a JWT token issued based on the provided username/password. I'd recommend to extend the token service (or use a different service) to issue a JWT token based on the provided SAML response - a token swap service. In many OAuth implementations it's called SAML grant type.
I cannot implement SAML to API service, my web service only used to load my app without server side logic, how can I implement SAML?
Usually after the authentication the user is redirected or posted to the SAML ACS endpoint URL, where the server can create sort of session (cookie, parameters, token, ..) and the user is redirected to a URL returned the web page with the session information.
If you are using an SPA, you could use a popup window or SAML with redirect (not with post), where the page could read the SAML response parameters (assertion, signature, ..) and use them in the token swap service mentioned above.
When processing the SAML response, try to use some mature, known, out-of-box libraries, it's a security service and not doing it properly may cause security weaknesses. But you need to do that on the server side, as at the end you need the JWT token consumed by the APIs.
We have a web application where the appThe lication is downloaded to the client using appcache and runnig int the client. It gets data into to via ajax calls. What it differes from the rest it we do not have a web server but the whole application is downloaded to the client is via an unauthenticated API call (via middleware server). Once the pages are downloaded to th client the login page is loaded and upon successful authentication the client will get a token for the session.
Now we want to secure this with SAML. But since we do not have a web server per say there is no way we can specify a URL (ACS) to redirect in SAML.
How do people implement SAML in this type of scenarios?
SAML only works through browser redirects.
You also have to have an IDP that supports SAML 2.0 e.g. ADFS.
The interaction is between the SAML application and the IDP. There is no 3rd party.
SAML is not ideal for mobile. OpenID Connect is a better choice. Either way, you have to add a client-side stack that supports the protocol to your application.
Also, SAML does not have a web API flow. OIDC does.
I'm writing an AngularJS SPA application which calls Rest full web service. Back-end is being written on JAX-RS, deployed on Tomcat 7. I'm using HTTPS, SSL for transferring data from SPA to JAX-RS
requirements
I have to make LDAP authentication. (I will send username & password to web service and it should make authentication)
I have to do user's session management (because, when authenticated user sends request to web service, user doesn't have to authenticate again)
problems
I think there are two options for doing LDAP authentication:
Make LDAP authentication using core java http://docs.oracle.com/javase/jndi/tutorial/ldap/security/ldap.html
Use Spring security (I'm not familiar with it and not sure if it's possible. I think I should send username & password to rest service. Rest service will have spring security library injected and it'll be possible to use authentication functionality. Am I right?)
Manage user sessions. Once user is authenticated, it should be saved somewhere, so that user can do operations until its logon is not expired.
How can I do it?
Which way should I choose? How should I make LDAP authenticating and session management?
Can anyone give any suggestion or example links?
So,
LDAP Authentication using JNDI works just fine, you could also use the neat UnboundID LDAP Java API. A simple LDAP Bind example can be found here: https://code.google.com/p/ldap-sample-code/source/browse/trunk/src/main/java/samplecode/bind/SimpleBindExample.java .
Note also that you could use a Node.JS module as your backend, the Passport.JS Authentication framework for example, provides lots of features/capabilities relative to authentication and Federation (i.e., do things like 'Login with Google', etc...). See: passportjs.org.
On the Angular/frontend side,your best bet is to use a JWT token. It's all explained in detail with examples here: http://code.tutsplus.com/tutorials/token-based-authentication-with-angularjs-nodejs--cms-22543.
In essence:
your backend Authentication REST should return a JWT Token in the response, once the user successfully binds to LDAP. This Token would contain some user data, and should be encrypted (see link above).
Your Angular App should set that token as a cookie on the client Browser ("set-cookie" response header) upon successful login (so in the Controller of your Login view).
The Client will then present that cookie/JWT Token on every request it makes to your app.
Your app will then need to validate the token presented on every request (in the controller of your SPA). You may also want to add the user authentication data to your $scope so you can use it in your view.
Hope it helps...