I have an application with Vaadin 8 and Spring Boot. Currently, I'm in progress of adding authentication to this app. So, I enabled Spring Security and started tinkering with it. Basically, I followed this tutorial: https://vaadin.com/tutorials/securing-your-app-with-spring-security/setting-up-spring-security
The approach, described there, works fine, however, I'm slightly disturbed by the fact that /VAADIN/** path needs to be publicly available (otherwise, Vaadin doesn't work). I mean, of course, I have protected particular pages by their paths (e.g. /admin) and unauthenticated users won't be able to open them, but isn't exposure of /VAADIN/** path dangerous? What if some hijacker tries to send some request to the Vaadin servlet outside of the UI (by simply curling it) with some specific headers/parameters? Is it possible that by formatting such request in some malicious way, the data will be actually returned to this hacker, bypassing Spring Security?
but isn't exposure of /VAADIN/** path dangerous
It is not dangerous per ce. The framework itself has just some generic parts there, like static resources for the client, like the widgetset and theme. Having said that, it is of course to be noted it application design. For example you should not put something that includes confidential info in your app as ThemeResource, but use ClassResource instead and things like that.
Related
I have a pretty basic vaadin application running. The application is spring-boot backed and I defined some rest API.
I've added OpenAPI documentation using org.springdoc:springdoc-openapi-ui:1.4.4, which worked perfectly before adding vaadin.
After adding the vaadin dependencies as shown in the vaadin spring-boot tutorial, and creating a view (which works), the swagger UI is no longer reachable.
It seems to me that vaadin completely takes over all web requests. Digging deeper, I've found that vaadin registers a new servlet and catches all requests.
I don't find any docs on how to configure this -- I'd expect that one could configure vaadin such that it serves UI from a different path, say /ui or similar.
I've tried to set
vaadin:
url-mapping: "/ui/*"
in my application.yaml -- but this results in blank pages (no errors) for my vaadin views,
and the vaadin servlet does still take over /.
I use spring.boot 2.3.2.RELEASE, vaadin 14.3.1.
The value to override is (note the camelCase instead of the kebab-case):
vaadin:
urlMapping: /ui/*
Using the kebab-case did (does) not work. As expected, this is a bug. See https://github.com/vaadin/spring/issues/637
From the docs at the point of time:
You can set properties for Spring Boot in your application.properties file.
Example: Setting Spring URL mapping in application.properties.
vaadin.urlMapping=/my_mapping/*
By default, URL mapping is /*.
An additional servlet, such as /my_mapping/*, is required to handle the frontend resources for non-root servlets. The servlet can be defined in your application class. See this Application class for a example.
Source: https://vaadin.com/docs/v14/flow/spring/tutorial-spring-configuration.html#using-spring-boot-properties
Is there a way to set a context path in a Spring Boot application running in GCP AppEngine Standard?
I want to add an implicit prefix to all my resources. So if the #RestControllers are, say, /a and /b, I want that to access them, their URL is always /my/prefix/a and /my/prefix/b. In normal, embedded mode in Spring Boot, this works by setting server.servlet.context-path. However, this setting is not respected by AppEngine. In it, /my/prefix/a returns a 404 and I have to use /a instead
How do I add a common prefix to all my resources in AppEngine Standard? This seems basic for AppEngine's services/modules support to avoid duplicating the prefix in all controllers, but I can't find how to do it
so per my conversation with the Google Cloud Support team - I got confirmation that the App Engine Standard does not support / honor the port & context paths set in spring-boot.
This is the response I got from them:
"With regards to your concern about App Engine not honoring the manually set port number and context path, this is because it should be setup in yaml file.
For the port to be set as 7777, it should be done by port forwarding. However, port forwarding is only available in App Engine Flex. For more details about this, you may visit this page [1].
For the context-path, you may use the tag and include in appengine-web.xml file. This sets the path in your application that contains the static files. You may check this document [2] for more information.
You could also include the tag in your appengine-web.xml as it is also useful for serving static content such as images, CSS stylesheets or JavaScript files. You may use this reference [3].
With this solution or workaround, this also address that spring-boot application could be deployed in App Engine.
If you have further concerns, just let me know.
Thank you and have a nice day!
[1] https://cloud.google.com/appengine/docs/flexible/custom-runtimes/configuring-your-app-with-app-yaml#port_forwarding
[2] https://cloud.google.com/appengine/docs/standard/java/config/appref#public_root
[3] https://cloud.google.com/appengine/docs/standard/java/config/appref#static_files
"
However, setting the to some value did not still pick it up as the context path. So had to abandon GAE unfortunately. Wasted so much time on this - hope this is useful for others that are struggling with this.
Anyone ever tried the following? (and was successful)
In a web application (A), I am using the <c:import> tag to get secured content from another web application (B) running on the same application server (WebSphere 7). Both apps use Hibernate and Spring's OSIV filter.
Looking at the import tag source, I see that the strategy is that if the url is relative then it includes the content using RequestDispatcher.include() .If the url is absolute, the code opens a URLConnection.
Since I need to keep track of the remote user, I can't do the following:
<c:import url="http://host:port/B/getContent">
Doing
<c:import url="/getContent" context="/B">
instead would work. But with this approach I am not hitting Spring's OSIV filter configured in B. The original (importing) request in A does go through the OSIV filter but it has no effect in B. Hence I am getting the usual "No session or session closed" error for lazy initializations of entities.
I am bit in a catch 22 here and I am wondering if what I am trying to do is actually feasable according to my requirements.
The bottom line is that I did manage to get what I wanted by aggregating my content directly from the client using Dojo, (I am using SSO so the identity of the user gets carried) but I would prefer the other way if it was possible.
I'm trying to find a simple, flexible way to add JaaS authentication to REST. I found a post that I think leads me in the right direction (See StevenC's answer). It sounds like the servlet container is responsible for security, not the Jersey code itself. I like this idea, but need a little guidance on implementation.
Grizzly is my servlet container and I want to configure it to use JaaS for authentication. For now, a simple username/password combination would be fine, and hard-coding the username/password pairs directly in code is fine. As long as it uses JaaS, we can refine those details later.
As far as what is sent over HTTP, I'm thinking that storing a cookie would be the easiest way to make this all work. Whatever it takes to keep authentication junk away from my Jersey code.
Here's the code to start Grizzly so far:
final String baseUri = "http://localhost:9998/";
final Map initParams = new HashMap();
initParams.put("com.sun.jersey.config.property.packages",
"my.jersey.Service");
System.out.println("Starting grizzly...");
SelectorThread threadSelector = GrizzlyWebContainerFactory.create(baseUri, initParams);
System.out.println(String.format(
"Jersey app started with WADL available at %sapplication.wadl\n"
+ "Try out %shelloworld\nHit enter to stop it...", baseUri, baseUri));
System.in.read();
threadSelector.stopEndpoint();
System.exit(0);
If this whole process works, what's the best way to check permissions for the user? I would probably want my REST code to actually validate permissions at certain points. Am I even on the right track? Is there an easier way? A link to a tutorial would be a great answer. Even an answer like "I did that and it worked" would give me a warm fuzzy that I'm heading in the right direction.
Thanks for any help.
EDIT: Some clarifications for StevenC's comment:
Do you still want to use servlet filters to protect your resources? I'll use whatever can separate out the authentication detail from the Jersey code. It doesn't have to be servlet filters.
What is mean by "configure it to use JaaS"? The original plan was to protect the current API using JaaS. The next phase would be to make the entire API available online. It seemed to make sense to have a Jersey wrapper around the API calls, but keep authentication handled by Grizzly. Grizzly would have to interact with JaaS at that point I believe.
Are you thinking there should be some config that simply causes grizzly to protect your resources? I was considering a two-step process of authenticating the user and based on roles, authorizing the user to access resources. The idea was to have Grizzly handle authentication (using JaaS) and Jersey handle authorization.
"I don't see the need for the usage of cookies with a RESTful resource." It would be wonderful to remove the use of cookies, but how can the be accomplished? The system needs to know if the user is authenticated. I'd rather not ask them to pass a username/password/etc for each call. Even passing a session token as a parameter with every call seems "ugly".
Also, please note that I'm fairly new to REST. I've been doing SOAP for a couple of years, so I may have a "SOAP bias" that may be blinding me from some obvious, simple solution that everyone uses. If there's an easier way, please feel free to share. I'm just trying to learn as much as possible.
I'm not entirely clear what is meant by "configure it to use JaaS for authentication". If there's a simple configuration to have grizzly enforce HTTP authentication protecting URLs, I don't know about it.
I'm assuming from the other question and answer you reference that you want to use a servlet filter. Normally that's configured in the web.xml file of a servlet project. Grizzly is of course often used to start up a server from code as opposed to application config. When I used grizzly in this way I noticed that GrizzlyWebContainerFactory didn't offer any versions of create() that allowed you to specify servlet filters. However I did notice ServletAdapter [1] in the same project that does give you that ability.
As for the filter itself, I unfortunately don't know of a pre-built servlet filter that simply plugs JaaS configured login modules into your application, so you'll likely have to write a bit of code there. It's not much though, just choose the HTTP based authentication method (e.g. HTTP BASIC, DIGEST, etc.), extract credentials from the request accordingly, and login using the JaaS framework. I don't see that a cookie would specifically be needed for RESTful resources. The RESTful architectural style frowns upon keeping sessions. There are plenty of tutorials about JaaS otherwise, so I won't elaborate on that here.
Once a JaaS subject is active (consumer successfully logged in) you can simply get the current subject and check the active principals and credentials using the Subject.getSubject method.
Anyway, this answer is specifically to give a bit more of the details around doing auth with servlet filters, as you requested in the other (linked) question. This isn't necessarily the only way to do auth in a jersey webapp, but it's a fairly straightforward way to do it. I like it because it keeps me from injecting repetitive auth code in each resource that needs it.
[1] https://grizzly.dev.java.net/nonav/apidocs/com/sun/grizzly/http/servlet/ServletAdapter.html
Not sure if you are asking how to secure each resource, but I found a presentation on javapassion that sounds like what you are looking for. He says to use #Context SecurityContext as a parameter.
#Path("basket")
// Sub-resource locator could return a different resource if a user
// is a preferred customer:
public ShoppingBasketResource get(#Context SecurityContext sc) {
if (sc.isUserInRole("PreferredCustomer") {
return new PreferredCustomerShoppingBaskestResource();
} else {
return new ShoppingBasketResource();
}
}
I am looking for a security framework for Java web application with Object granularity.
What it means is that I don't just want to filter by urls or by roles, but by specific user ownership of domain objects inside the system.
For example, if there is a Message object that has a Sender user and a Receiver user I would like to be able to configure it so that every Message can be RW by its sender and RO by its receiver.
Or for example, all user profiles are viewable by all users but editable only by the owner.
This rules, of course, I would like to define them with meta data (annotations, xml files, whatever) and not embedded in my business logic.
Is there such a beast out there? Preferably open source.
Spring Security can provide things like method security and "secure objects" using AOP.
You're looking for access control lists (ACLs). Like the other respondents I think Spring Security is worth checking out here--Acegi is just what Spring Security used to be called before they renamed it. Spring Security does have explicit support for ACLs (in addition to URL-based, role-based and group-based access controls). It supports both XML and annotation-based configuration. And you can apply ACL filtering to the view (using taglibs to decide what to render or suppress in the JSP), to methods that return a single domain object (decide whether to allow the method call to succeed), and to methods that return a collection (decide which objects to filter out of the collection before returning it).
You might be able to get away with rolling your own ACL code for simple requirements, but in my opinion ACLs can get tricky pretty quickly. Especially if you have lots of domain objects and you have to start taking performance management seriously.
Check out this link Acegi Security Fundementals - it's slightly outdated but still gives you the main concepts of Spring Security's object level authorization mechanisms.