Authorization in Helidon MP - helidon

Helidon uses annotations like
#RoleValidator.Roles({“my_admins”, “test”})
to do the authorization.
I am wondering if there is a way to do authorization differently using configuration settings for paths, for example.
Basically, the question is.
Is there a way to use configuration instead of annotation to authorize requests to particular endpoints?
If yes, would it be possible to get the SecurityContext like in a case of annotation?
Example with multiple roles for one endpoint would be helpful
I am successfully using annotations but in some cases it is not convenient

You should be able to do what you want using configuration instead of annotations. It would look similar to what our documentation describes here: https://helidon.io/docs/latest/index.html#/se/guides/security-oidc#Restrict-access-to-a-specific-role
You might not even use the annotations given your use case.
You would define the user-to-roles mapping however makes sense for you (Helidon config would work as would some other provider) and then use Helidon config to set up each endpoint's roles-allowed setting as needed.
As you are using Helidon MP, you could for example add something like this to your META-INF/microprofile-config.properties file:
web-server.paths.0.path=/greet
web-server.paths.0.methods=get
web-server.paths.0.roles-allowed=admin,dev
web-server.paths.0.authenticate=true
(These particular settings are drawn from Helidon's MP QuickStart example but you get the idea.)

Related

is there a way to configure mTLS in Helidon MP without saving the certificates to the disk?

is there a way to configure mTLS in Helidon MP without saving the following to disk?
server.sockets.0.tls.trust.keystore-path
server.sockets.0.tls.private-key.keystore-path
client.tls.client.keystore-path
If we have these certificates as a Java object is there a way to pass those to the Helidon server?
I am using Helidon MP 2.3.1
I have tried configuring it with certificates on disk but I would like to avoid that.
From David Kral, there is no "easy" way to do this. Basically there are two possible options for you.
It is possible to create a new config with runtime created ConfigSource and instead of setting resource.resource-path one could use resource.content . The value here is Base64 encoded resource value. That means, you can store obtained certificate there.
Alternatively, you could create your own CDI extension. Inject ServerCdiExtension there and create initialization method (Similar to how ServerCdiExtension#startServer method looks like in terms of parameters). In this method you can obtain WebServer.Builder from injected ServerCdiExtension instance and it is possible to set Tls configuration the way you want it to be set. It is important to note, this extension has to have higher priority over theServerCdiExtension .

API Versioning in dotnet core

I am working on APIs in dotnet core 2.2 and I'd like to version my API.
I'm looking for some solutions except:
Routing method (api/v1/controller, api/v2/contoller)
Routing method using APIVersioning package, (api/v{version: apiVersion}/contoller})
I want to know if there is any other solutions in which I don't have to change the route attribute? I might be completely wrong but can I use middleware? Like, map delegate to map the the incoming requests (based on v1, v2 it carries) to its right controller?
I'll highly appreciate any feedback and suggestions.
You can use the APIVersioning package and configure it so it selects the version based on the HTTP Header.
services.AddApiVersioning(c =>
{
c.ApiVersionReader = new HeaderApiVersionReader("api-version");
}
And then you can use the [ApiVersion] attribute on your controllers.
Can you use custom middleware - yes; however, be advised that endpoint selection is typically much more involved. The routing system provides extension and customization points, which is exactly what API Versioning does for you. Creating your own versioning solution will be a lot more involved than having to add a route template parameter.
If you're going to version by URL segment, then API Versioning requires that you use the ApiVersionRouteConstraint. The default name is registered as apiVersion, but you can change it via ApiVersioningOptions.RouteConstraintName. The route parameter name itself is user-defined. You can use whatever name you want, but version is common and clear in meaning.
Why is a route constraint required at all? API Versioning needs to resolve an API version from the request, but it has no knowledge or understanding of your route templates. For example, how would ASP.NET know that the route parameter id in values/{id:int} has be an integer without the int constraint? Short answer - it doesn't. The API version works the same way. You can compose the route template however you want and API versioning knows how and where to extract the value using the route constraint. What API versioning absolutely does not do is magic string parsing. This is a very intentional design decision. There is no attempt made by API Versioning to try and auto-magically extract or parse the API version value from the request URL. It's also important to note that the v prefix is very common for URL segment versioning, but it's not part of the API version. The approach of using a route constraint negates the need for API Versioning to worry about a v prefix. You can include it in your route template as a literal, if you want to.
If the issue or concern is having to repeatedly include the API version constraint in your route templates, it really isn't any different than including the api/ prefix in every template (which I presume you are doing). It is fairly easy to remain DRY by using one of the following, which could include the prefix api/v{version:apiVersion} for all API routes:
Extend the RouteAttribute and prepend all templates with the prefix; this is the simplest
Roll your own attribute and implement IRouteTemplateProvider
Ultimately, this requirement is yet another consequence of versioning by URL segment, which is why I don't recommend it. URL segment versioning is the least RESTful of all versioning methods (if you care about that) because it violates the Uniform Interface constraint. All other out-of-the-box supported versioning methods do not have this issue.
For clarity, the out-of-the-box supported methods are:
By query string (default)
By header
By media type (most RESTful)
By URL segment
Composition of n methods (ex: query string + header)
You can also create your own method by implementing the IApiVersionReader.
Attributes are just one way that API versions can be applied. In other words, you don't have to use the [ApiVersion] attribute if you don't want to. You can also use the conventions fluent API or create your own IControllerConvention. The VersionByNamespaceConvention is an example of such a convention that derives the API version from the containing .NET namespace. The methods by which you can create and map your own conventions are nearly limitless.

Spring Auto REST Docs + Spring Data REST? HATEOAS?

I really like the idea of using Javadoc comments for auto-generating REST Docs!
Huge parts of our REST API are automatically generated by Spring Data REST (by adding #RepositoryRestResource to Repositories). It would be great if REST Docs could also be generated for these - that would be a very high degree of automatition.
But unfortunately most "auto-"snippets are "empty" (e.g. auto-response-fields.adoc only contains a list of links[]-Attributes). I guess the reason could be that the REST Controllers are probably created dynamically by Spring Data REST. Currently I do not see how to re-use the Javadoc comments for them.
Is there any way to auto-generate REST Docs for such REST APIs that are provided by Spring Data REST?
It would even be helpful to manually tell Spring Auto REST Docs which classes are used in requests and responses instead of letting it discover it statically - is that possible?
And we also add HATEOAS "_links" to most response Resources (by providing ResourceProcessors as Beans). These links contain "title"s which are used by Spring REST Docs - if we list all of them with HypermediaDocumentation.linkWithRel(...). This is a bit redundant, and it would be nice if all the _links with "title"s could be processed automatically. (But this can be done by listing all of them in some extra code, so it is not as bad as with Spring Data REST.)
If necessary, I could also create an example project for what I am talking about.
Answer to the question whether one can manually tell Spring Auto REST Docs which classes to use for the documentation:
Spring Auto REST Docs allows to specify the request and response classes to use for the documentation. This can be done with requestBodyAsType and responseBodyAsType. In a test it looks like this:
.andDo(document("folderName",
requestFields().requestBodyAsType(Command.class),
responseFields().responseBodyAsType(CommandResult.class)));
This is from a test in the example project.

How can I cosume a GET REST call and mapping to a java bean (object) through Apache Camel?

I am new in apache camel. I want to do a GET REST call to get data and then I want to mapping these data to my Java bean. How can I do that with camel? I want to do it in a spring MVC web application.
I know how to do it with RestTemplate for example, but I want to use apache camel.
I've checked this documentation http://camel.apache.org/cxfrs.html but still I don't know how to set up for accomplishing this.
Please if you can provide some examples will be great.
There are a few different options. I'll walk through one...
First, define your rest configuration with bindingMode=auto
restConfiguration()
.component("jetty").host("0.0.0.0").port(9000)
.bindingMode(RestBindingMode.auto);
Next, when you define your particular rest service, specify a type (this is the type of the incoming body:
rest("/")
.put("/A/{subpath1}/{subpath2}")
.type(MyPojo.class)
.to("direct:XYZ");
That's it! The unmarshalling will be magical ;)
Alternatively, you can unmarshal things yourself.
If you'd like to see a working example of the above, check out this program: it has a main() to test it. https://github.com/DariusX/CamelSandbox/blob/master/CamelSandbox/src/main/java/com/zerses/camelsandbox/rest/RestConsumerBindingTest.java

Spring Security based authentication for a REST service

I'm in the process of implementing a REST service with Spring MVC and Spring Security (both 3.0.5). I'm using the security namespace not defining the Spring beans by hand.
I'm having some difficulties with the login process. What I'm trying to achive is this:
a POST to a /login URL would begin the authentication process.
There should be no actual form, so I'm not using the form-login... element. Without this element, the UsernamePasswordAuthenticationFilter isn't present on the security chain, so I thought I'd add it via a custom-filter... element and go on from there.
That's the gist of it, not for the questions:
is this a good way to implement authentication?
how exactly should I add this filter and on what position in the filter chain?
is it enough to add this filter or do I need something else as well?
Any feedback is appreciated.
Thanks.
In general, if you want to customize your authentication, you should use the bean configuration. I found the namespace based configuration suitable only for demo-apps. Here are my answers to your questions:
1) As I said above, you should use beans. Check this article for more information:
http://blog.springsource.com/2010/03/06/behind-the-spring-security-namespace/
But what you are going after will also work, with the requirements you have mentioned so far.
2) It should be added like this:
<http>
<custom-filter position="FORM_LOGIN_FILTER" ref="myFilter" />
</http>
<beans:bean id="myFilter" class="org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter"/>
3) Note that this filter would also perform default redirection to the original request. So if you do not need any redirection and just simple HTTP 200 should be returned back to client, you should implement your own AuthenticationProcessingFilter.
I hope it helps.