I wrote my first backend spring boot application.
I also created a seperate frontend application.
I would like to create a standalone basic authentication microservice.
The authentication thechnology is currently not relevant. It can use JWT, OUTH2, OKTA, whatever.
I emphsize the MICROSERVICE, rather than adding classes to an application code.
This is because all that I could find on the web and in several books was adding this authentication part as an embedded code in a whole spring boot application.
I would like to build an authentication seperate microservice, such the my other microservices (currently I have only one SP, but there will be more), will be able to use it in order to authenticate the users.
I hope I explained myself right :)
Could you please give me pointer for the correct implementation, or some updated tutorial which can help me accomplish this task?
UPDATE:
I have found a really great and up to date tutorial:
https://dzone.com/articles/step-by-step-a-simple-spring-boot-microservices-ba
Enjoy!
Thanks!
As you need an authentication service, you could work on validating the token generated by the authentication microservice.
You could:
Return a token from your authentication microservice;
Create a token validation service in your main microservice
The link below shows how to implement the authentication application in a manner that it works like an authentication gateway through JWT:
https://medium.com/#mool.smreeti/microservices-with-spring-boot-authentication-with-jwt-and-spring-security-6e10155d9db0
Alternatively, you could add a 3rd party solution to be linked to Spring Security. For this option, something like the code bellow in application.yml should work:
spring:
security:
oauth2:
client:
registration:
sts:
provider: sts
client-id: ${STS_CLIENT_ID}
client-secret: ${STS_SECRET_ID}
client-authentication-method: post
authorization-grant-type: client_credentials
provider:
sts:
token-uri: ${STS_URL}
In my opinion, both ways are valid. It depends on your context and scope.
Related
I have a question regarding the oauth2.0 openId and spring boot. I am developing a personal project, and I have deployed a Keycloak instance as an Auth server and I am writing code for the resource server. I would like to ask you some questions regarding security. As the Spring Docs say, we need only the issuer-uri of the Auth Server and the Resource Server will use this property to further self-configure, discover the authorization server’s public keys, and subsequently validate incoming JWTs. For example a resource server will have to specify the following:
spring:
security:
oauth2:
resourceserver:
jwt:
issuer-uri: <uri>
However, this means that any resource server can use my deployed Auth Server to self configure just by knowing the issuer-uri is there any way to protect the Auth Server from resource server APIs(that are external to my application)?
Thank you in advance!
i m new with spring security.
I want to know if it's possible to have jwt authentication server separate from resource server,
If possible i need a working example.
Thanks!
You could find an example with Oauth2 and Spring Boot 2.1.9.RELEASE here:
https://github.com/buddhiprab/springboot-oauth2-separating-authorization_server-and-resource_server
All the explanation of this example is here: https://medium.com/#buddhiprabhath/spring-boot-oauth-2-0-separating-authorization-service-and-resource-service-1641ebced1f0
This is doing with the client-credentials flow from OAuth2.
Here is another example using password flow:
https://www.javainuse.com/spring/springboot-oauth2-password-grant
Here's an example that shows a separate auth and resource server. This is from Joe Grandja, who is one of the primary authors of Spring Security:
Old way; Spring Security version 5.1 or earlier with separate spring-security-oauth library: https://github.com/jgrandja/spring-security-oauth-2-4-migrate
New way; Spring Security 5.2+: https://github.com/jgrandja/spring-security-oauth-5-2-migrate
Thank`s everyone! i start to understand how it works! i want to integrate jwt now!
I'm programming a client (Spring Boot application) which has to provide two endpoints for a user, one which uses Authorization Code Grant, and the other which uses Resource Owner Password Credentials Grant. Endpoints are on different URLs. The other one will be used by internal application so I'm not concerned about security.
I have an external OAuth2 server (both authorization and resource server) - so I'm not programming those but I have full access to their configuration. Keycloak is in question.
I've managed to set up Authorization Code Grant, but cannot get the other one to work.
My application.yml looks something like:
security:
oauth2:
resource:
token-info-uri: ...3rd party...
userInfoUri: ...3rd party...
client:
client-id: ...
client-secret: ...
grant-type: authorization_code
registered-redirect-uri: http://localhost:8080/app/auth_grant
pre-established-redirect-uri: http://localhost:8080/app/auth_grant/
user-authorization-uri: ...3rd party uri...
access-token-uri: ...3rd party uri...
scope:
- read
- write
- openid
I have an WebSecurityConfigurerAdapter implementation annotated with #EnableOAuth2Sso
#Configuration which permits only /login to be accessed unauthorized.
Now I want my users to be able to login with Resource Owner Password Credentials Grant at (example) /login_ROPCG.
I've read the documentation but I guess I've headed in the wrong direction. Can you give me some hints?
I've read this comment: Spring Boot Oauth2 use multiple grant_types for for same URL
In which the hint is that I need two different security configurations with different mapping but I don't know how to do this.
I've read this: How can I implement Basic Authentication with JWT authentication in Spring Boot? but I don't see how to set two different grant types.
And because of this I'm not sure is this even possible:
https://github.com/spring-projects/spring-boot/issues/14554
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')")
Now, I use Spring boot version 2.0.0.RELEASE and Swagger version 3.1.6 and Keycloak of Jboss. I would like to know how to configure in application.yml then let swagger can get access_token from Keycloak.
Thanks for your help
An initial decision to make is whether to say that the user accessing the swagger page needs to have an access token (i.e. the url pattern for swagger is secured and the user has to log in to get to swagger) or you exclude the swagger URLs from keycloak so that its UI can be accessed without needing a token.
If you're using the keycloak spring boot adapter then the URL patterns to secure (and which roles are required to access them) are configured in the application.yml or application.properties file as security-constraints. As properties an example is:
keycloak.security-constraints[0].authRoles[0]=user
keycloak.security-constraints[0].securityCollections[0].patterns[0]=/customers/*
This could be translated to yaml as:
keycloak:
security-constraints[0]:
-authRoles[0]: user
-securityCollections[0]:
-patterns[0]: /customers/*
(Real yml example at https://github.com/codemonkeybr/skip/blob/master/skip-cart/src/main/resources/application.yml#L29 )
Anything not covered by security-constraints is not restricted. There's a similar way of doing this with spring security if you're not using the official keycloak adpater - normally then you do it in a SecurityConfiguration java class.
Then you face decisions based on your chosen oauth2 flow and whether you use the 'try it out' feature. You can display descriptions without necessarily needing a token but 'try it out' does need a token. That yaml example above also has a way of telling swagger the token issuer url:
swagger:
auth:
token-url: ${keycloak.auth-server-url}/realms/${keycloak.realm}/protocol/openid-connect/token/
client-id: skip-local
That config is read by a java swagger configuration class and is part of a whole example that you could run. This specific question of how to configure swagger to work with an oauth2 token is not specific to keycloak and is general swagger-oauth2 configuration for which there is a guide at baeldung and there's an example using a different mode in Keycloak integration in Swagger