I have a spring cloud oauth #EnableAuthorizationServer that uses a jpa backend to store the accounts. I also have a couple of different clients, a website, an intranet and a ionic mobile app.
all the clients have separate client credentials inline in the oauth config block.
i have then tried to use the spring cloud sso to not have to login again.
my problem is that I want to remove the authorize step since all my clients are known to me and i simply want the user to be logged in across all my apps.
is this possible with spring cloud sso?
The authorization happens on the authorization server (so nothing to do with Spring Cloud). A UserApprovalHandler would do what you need, but the default one should work if you just set autoapprove=true (or a pattern matching te scopes you want to auto approve) in the client details. (Assuming your auth server is Spring OAuth.)
Related
I have a spring based application which does authentication and authorization(oauth2 based) for a client app.I want to now use keycloak to manage my authorizations, but i want to keep my spring code. Basically i want to use my existing auth code as an external identity provider in keycloak.
I am thinking of adding changes in client app such that it receives token from my existing oauth code(which does the authentication) and then exchange this token with keycloak(for session and authorization management). How can i do this? What configurations need to be done in keycloak?
I read about token exchange in keycloak here, but i am not clear about the kind of token i need to send from my existing auth code.
https://www.keycloak.org/docs/latest/securing_apps/
Here is how OAuth2 roles are usually spread:
Keycloak is authorization-server
Spring service is resource-server
front-end is client
user is resource-owner
I have a doubt of you wanting your Spring service to be "authorization-server" as well (serve user identity). If so, I think you should not.
Keycloak (or any other OpenID provider) should be the only authorization-server. Both Spring and client(s) should be configured to use it as so.
To write it differently, Keycloak is responsible for users login and emitting tokens with user ID (subject) and rights (roles or whatever). Other tiers in the architecture (clients & resource servers) get user info from the token and apply relevant security checks (spring security annotations, Angular guards, etc.).
I published a mono-repo for a meetup with minimal sample involving a Spring resource-server and Angular (with Ionic) client talking to a Keycloak OpenID authorization-server. You might find some inspiration browsing it.
is possible create authorization server for PKCE authentication in current version of spring security?
I did research and I found out this authorization server project https://github.com/spring-projects-experimental/spring-authorization-server but there is no usable sample for that project.
I also find out that spring recommends Keycloak as authorization server, but it is not fit for my case.
We need be able fetch and verify user against remote service, and then use authorization server only for generating and verifying jwt tokens. In my knowledge Keycloak should holds also users right? So the best solution would be custom spring standalone authorization server. Is it possible in some way? Thank you!
You may have a look to this project: CloudFoundry User Account and Authentication (UAA) Server.
UAA is a (Spring MVC) component of Cloud Foundry but it could be used as a stand alone OAuth2 server. It can support external authentication service. And there is a Pull Request that implements PKCE: https://github.com/cloudfoundry/uaa/pull/939 (not yet merged, but under review).
You can find an example on how to use UAA on baeldung.com.
As far as I know, Spring framework has one more implementation of the authorization server. It is a part of spring-security-oauth project. But this project was moved into maintenance mode.
According to this migration guide, the new authorization server project (that you have already found) will be created to change the legacy solution.
From my point of view now there are several possible options:
Using old legacy spring-security-oauth. More examples with old auth server
Using external services like Keycloak, Auth0, Okta and etc
Our stack includes the following services, each service runs in a docker container:
Front-end in React
Backend service based on Spring boot "resource-service"
Keycloak
Other backend service (consumer)
Both the front-end and the consumer services communicate with the backend using REST API.
We use Keycloak as our user management and authentication service.
We would like to integrate our Spring based service "resource-service" with Keycloak by serving both web application and a service flows:
Web application - React based front-send that should get a redirect 302 from the "resource-service" and send the user / browser to login in the Keycloak site and then return to get the requested resource.
Server 2 Server coomunication - A server that need to use the "resource-service" API's should get 401 in case of authentication issues and not a redirection / login page.
There are few options to integrate Spring with Keycloak:
Keycloak Spring Boot Adapter
Keycloak Spring Security Adapter
Spring Security and OAuth2
I noticed that there is a "autodetect-bearer-only" in Keycloak documentation, that seems to support exactly that case. But -
There are a lot of integration options and I'm not sure what is the best way to go, for a new Spring boot service.
In addition, I didn't find where to configure that property.
I've used approaches one and two and in my opinion, if you are using Spring Boot, use the corresponding adapter, use the Spring Security adapter if you're still using plain Spring MVC. I've never seen the necessity for the third approach as you basically have to do everything on your own, why would anyone not use the first two methods?
As for using the Spring Bood adapter, the only configuration necessary is the following:
keycloak:
bearer-only: true
auth-server-url: your-url
realm: your-realm
resource: your-resource
And you're done. The bearer-only is so that you return 401 if a client arrives without a bearer token and isn't redirected to a login page, as you wanted. At least that's what's working for us :-)
After that, you can either use the configuration for securing endpoints but it's a bit more flexible to either use httpSecurity or #EnableGlobalMethodSecurity which we're doing with e. g. #Secured({"ROLE_whatever_role"}).
If you're using the newest Spring Boot version combined with Spring Cloud, you might run into this issue.
I configure my resource-servers to always return 401 when Authorization header is missing or invalid (and never 302), whatever the client.
The client handles authentication when it is required, token refreshing, etc.: Some of certified OpenID client libs even propose features to ensure user has a valid access-token before issuing requests to protected resources. My favorite for Angular is angular-auth-oidc-client, but I don't know which React lib has same features.
Keycloak adapters for Spring are now deprecated. You can refer to this tutorials for various resource-server security configuration options. It covers uses cases from most simple RBAC to building DSL like: #PreAuthorize("is(#username) or isNice() or onBehalfOf(#username).can('greet')")
I have two spring boot application. One is Rest and the other one is Spring boot web MVC app which consumes the Rest. The Rest has spring security configured and I want to login/logout from the client app. The client app has nothing but view and controllers to interact with the rest api.
I am using rest template to interact with the api now.
If the client app is not secured so any other anonymous app may do the same, and this is not security, it's a sieve ...
If you want to create a custom authorization/authentication, you can create own protocol and use tokens/JWT (possibly, OpenID or other global technology) and exchange information between applications.
But there is technology to do it all centrally and reliably - OAuth2, and Spring has it 'from the box' - authorization server, resource server, client. The most advantage - multiple applications (clients), one authorization - you create one user and can authenticate it on any client with the same credentials. You can customize it with JWT, and use any data in the access token and as a consequence get any information about principle/authorization.
I have gone through many posts and articles but didn't find a straightforward solution for the case below which I have to implement.
Platform: Spring Boot 2.x.x (Spring Security 5.x.x) with embed Tomcat
Solution: REST service that consume many client apps and many end users.
I have to implement a REST end point /api/search which accessible for many client application. As an example, web application APP-X (Angular), web application APP-Y(Jquery/Bootstrap) and mobile application APP-Z (IOS). All three clients are separate entities (both technical perspective and business perspective).
So I have to authenticate above application using onetime token. Therefore I planned to go for Spring OAuth2 by enabling #EnableAuthorizationServer and #EnableResourceServer. For each app client I’ll generate a token and they can use it when they connect with my REST service. Is this approach correct?
Apart from the app clients system has capability to register and login functionality for end users. Also my end point (/api/search) can access both anonymous users and users who registered under ROLE_REGUSER role. And through the security context, I need to access the user details as usual user authentication.
This is the place I got stuck. How can I handle the following points together using Spring Security 5.x.x (Spring Boot 2.x.x).
I. Both client apps and end users authentications.
II. Allow access for anonymous users and registered users for same end point.
I have attached small diagram to elaborate the above scenario.
Thanks
I found a solution when I upgraded my spring security version to 5.2. In version 5.2, they have depreciated #EnableAuthorizationServer and #EnableResourceServer. So I had to move with an external authorization provider who supports auth2. I chose AWS Cognito, and fulfill the above requirement, using the user pool option.
In AWS Cognito
I created a user pool.
Then created two app clients in the same user pool.
One app client configured as support to the client credentials flow.
The second app client configured as support to the user authentication flow.
In client applications
Retrieve access token directly from AWS Cognito using client credentials and used to secure all API calls.
If a user login at any stage, retrieve access token directly from AWS Cognito using the authorization code and replace any existing access token.
The advantage is, the resources server can validate any access token that generated related to the same user pool.
In resources server (backend API/Spring Boot)
Validate access token.