Use #EnableResourceServer with custom Authorization Provider - spring-boot

I'm trying to find what classes I need to implement in order to use the #EnableResourceServer annotation and interact with our custom OAuth2 server and token storage.
The goal is to package it as a library and share it across other services. So basically I need to implement:
Custom Token endpoint.
Custom Refresh endpoint.
Custom token validation filter (to avoid the call to /check_token) since we are using JWT, we are ok with just making sure the token is properly signed.
Save the token (on the resource service) in Redis.
The custom endpoint to retrieve the user information.
So far I've seen the following classes:
TokenEndpoint
RefreshTokenGranter
OAuth2AuthenticationProcessingFilter
But since I haven't been able to find much documentation, I'm wondering whether I'm a bit lost or these classes are not intended to be overridden and it will be better to create my custom logic and not rely on the #EnableResourceServer.

I believe where you might want to start looking is ResourceServerSecurityConfigurer and ResourceServerConfigurerAdapter. This follows a similar programming model to WebSecurityConfigurerAdapter and will give you some context for what can be configured.
From there, take a look at ResourceServerTokenServices and TokenStore for points 1, 3, 4, and 5.
Now, regarding #2, since you'd also like to have applications refresh tokens, it sounds like you might want to create two libraries, one for services that want to authorize requests using OAuth2 (#EnableResourceServer) and one for services that want to address those resource servers (#EnableOAuthClient). In that case, also take a look at OAuth2RestTemplate and ClientTokenServices.
Also, take a look at http://projects.spring.io/spring-security-oauth/docs/oauth2.html if you haven't already as this is where I pulled most of the above from.
There are some examples at https://github.com/spring-projects/spring-security-oauth/tree/master/samples/oauth2 that you might find helpful on the Resource Server side, specifically https://github.com/spring-projects/spring-security-oauth/blob/master/samples/oauth2/sparklr/src/main/java/org/springframework/security/oauth/examples/sparklr/config/OAuth2ServerConfig.java
And there is an example of a client at https://github.com/spring-projects/spring-security-oauth/blob/master/tests/annotation/client/src/main/java/client/ClientApplication.java
Hope that helps!

Related

How to redirect user request to other Restful API that runs on other server in Spring boot?

I am a noob in spring boot. I am writing a Gateway for some services. In a condition, I need to forward user request to other services (some Restful API) after authentication. I have done some search on 'forward' and 'redirect'. I think I need 'forward'. But I still have some questions: 1. when I forward it to other URI(eg. abc.dce.com/service/), does the service get the request body. 2.How can I do it in spring boot? Do you guys have a good example that fit my condition? (I admit that I am kind of lazy for this, but there are really many style of forward that confused me.)
//I find this example, but this is forwarding to service in same package //under same Internet.
#Override
public void addViewControllers(ViewControllerRegistry registry) {
// forward requests to /admin and /user to their index.html
registry.addViewController("/portal").setViewName(
"forward:/app/index.html");
}
Since you mention you're new to spring boot, you might want to take a look at spring project that implements a fully-featured gateway. I've used an earlier version of it (zuul) and the current spring-cloud-gateway allows you to implement a complete gateway easily by creating a spring-boot project and configuring. It has a lot of features you'll likely want to implement as a gateway (like adding/removing headers, modifying payloads,..). If you need features they don't support, you can implement via filters and other interfaces they provide. This was initially opensourced from Netflix so it is fairly comprehensive.
https://spring.io/projects/spring-cloud-gateway
Sample project:
https://github.com/spring-cloud-samples/spring-cloud-gateway-sample

Implementing filter-based JWT authentication vs OAuth2 JWT authentication on Spring Boot 2

As I can understand, OAuth2 framework needs a custom JWT authentication server and I have to create a custom security filter with JWT utility class for the filter-based JWT implementation.
However my question is, what is the best method to implement JWT on Spring Boot 2? filter-based authentication or OAuth2?
Is there any pros and cons based on nature of the clients and application?
As an example; Does OAuth2 authentication provide any advantage, if application manages different clients such as mobile, web, web service etc.?
Note: My question is related to the security of Spring-Boot REST API + web application.
I have found a discussion regarding the same matter and I’m extracting the important points below.
From the technical point of view, still I didn’t get a clear idea of which implementation, when and where, but it helps me to take a decision.
I personally hesitate to bring in OAuth when I only need JWT authentication. It feels confusing and honestly I do not want the additional complexity to use #EnableResourceServer etc. Maybe it's just a couple of lines of configuration but if feels like overkill.
Can someone show me why it's so difficult to set up an OAuth2 provider with JWT tokens? If you want JWT tokens all the code is already here. Why is it so hard to just use it?
Answer:
Maybe it's not difficult but 1) it feels unnatural to do so and 2) it can be easier.
Instead of using #EnableResourceServer and other setup I would like something much more easier like:
#Override
protected void configure(HttpSecurity http) throws Exception {
http
.jwt()
.loginUrl(new AntPathRequestMatcher("/api/login", "POST"))
.secret("my-super-duper-secret")
.claimsProvider(new MyClaimsProvider)
What you typically want set to for JWT is the login url (can be defaulted to /login), the secret and optionally some claimsProvider implementation. A default implementation should be provided out of the box adding the username and roles to the claims.
This way it would be very easy to setup JWT in Spring Security.
With OAuth2 there is a "refresh token", so you put the onus on the client to keep the access token live, and the authorization server can check the user account every time it is refreshed. If you start worrying about that kind of problem (which you should) then you will end up implementing something that is getting pretty close to OAuth2, at which point you might say "why didn't we just use OAuth2 in the first place?" Do you see my point?
Isn't the use case described in this issue conceptually different from the OAuth2 case? Here we have a password as an input and JWT token as an output, and JWT token is then used for accessing the resources. The JWT profile for OAuth 2 spec specifies a different case, where a JWT token is an input to the token service and the access token is an output, and access token is then used for accessing the resources.
It will be good to have just simple JWT token base authentication without OAuth which is sometimes complicated for small projects.
https://github.com/spring-projects/spring-security-oauth/issues/368

Setup Spring Filter using annotation

I am really new to spring and wanted to make a simple web application that uses JWT based authentication.
I have an endpoint on my server (/token) that returns JWT tokens to my client.
These clients then make requests to my server using that token. I was wondering how I could implement something like this:
#Secured("Admin")
#RequestMapping("/users", method=RequestMethod.DELETE)
public #ResponseBody String deleteUsers(){
...
}
From what I could gather, I would need a filter that would validate my JWT token that is sent along with every request the client makes. Is there any way in which only requests that have a #Secured annotation are passed through that filter?
Spring Security maintains a filter chain internally where each of the filters has a particular responsibility and filters are added or removed from the configuration depending on which services are required. The ordering of the filters is important as there are dependencies between them. If you have been using namespace configuration, then the filters are automatically configured for you and you don't have to define any Spring beans explicitly but here may be times when you want full control over the security filter chain, either because you are using features which aren't supported in the namespace, or you are using your own customized versions of classes.
link

Authentication and authorization in Spring Data REST

I am implementing a Spring Data REST based app and I would like to know if there is an elegant way to implement authentication and authorization rules using this framework or related frameworks.
All HTTP requests to the REST server must carry authentication headers, I need to check them and decide to authorize or not based on the HTTP method and the association of the authenticated user with the resource being requested. For example, (the app is the REST server of an e-learning system), the instructors can access only their own course sections, students can access only the courses sections they are subscribed, etc.
I would like to know if there is a default way to implement authorization in Spring Data REST. If the answer is no, could you make a suggestion for my issue? I am thinking about:
Servlet Filters
Spring Security
Spring Data REST Handlers (how to access the HTTP headers?)
The best bet for you is Spring Security.
That would help you achieve authorization is much simpler manner.
Spring Security would require you an implementation that looks at request headers and performs the log-in operation programmatically.
Refer the accepted answer here.. I had followed the same and implemented the security layer in front of my rest services ( which were build using RestEasy )
RESTful Authentication via Spring
There is an alternate method as well..
Refer
http://www.baeldung.com/spring-security-authentication-provider
In both cases you can disable the session creation by declaring the stateless authentication in spring security, this would help you improve the performance considerably when large volume of hits are made to the state-less REST services..

What is the correct way to configure spring security to accept JSON based requests

I'm trying to figure out what the correct way to configure SpringSecurity is to receive, respond to json based authentication requests.
There appear to be two ways to do this :
Use the spring security configuration to route authentication requests to a Controller...see http://raibledesigns.com/rd/entry/implementing_ajax_authentication_using_jquery
Create a new AuthenticationFilter, AuthenticationSuccessHandler, AuthenticationFailureHandler...see https://github.com/loiane/spring-security-extjs-login
It looks like the AuthenticationFilter method fits into the framework better, and ensures that filters that come afterward in the chain execute.
Anyone know what the pros/cons of either approach are?

Resources