Spring Security with path variable parameters - java

I would like to create security rules based on custom url parameters (path variables).
In example. Let say I want to have user that has admin access for resources called Brand1 and Brand2 but has no access to resource called Brand3. We may edit resources using following links.
http://myapp/brand/edit/1
http://myapp/brand/edit/2
http://myapp/brand/edit/3
now in security context I would like to do something like that
<security:intercept-url pattern="/brand/edit/{brandId}"
access="hasRole('ROLE_ADMIN') or
#authorizationService.hasBrandPermission(
#brandId, principal.username)"/>
The only thing I get is username. BrandId is always null.
I used to do that with #PreAuthorize and it worked but now I would like to centralized security configuration in single xml file instead of spreading it across all controller classes. Moreover when I was using #PreAuthorize my access-denied-handler did not redirect me into denied page but display ugly AccessDeniedException insead.
I would really aprecieate any ideas.

Change the Spring Security version in your pom.xml to 4.1.0.RELEASE:
<spring-security.version>4.1.0.RELEASE</spring-security.version>
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-web</artifactId>
<version>${spring-security.version}</version>
</dependency>
You may need to clean your maven project after that.
(I know, it's an old question. Nonetheless, I faced same issue 3 years later).

you can try using regular expression.
you will need to add the attribute path-type="regex" in your http element or request-matcher="regex" if your using spring security 3.1
see the documentation for more details

Related

What is the actuator endpoint to which the togglz library exposes the edit options

I have recently being exploring the togglz library for feature management in Spring Boot application.
In the documentation here , its mentioned that I can use the actuator endpoint
http://localhost:8080/actuator/togglz/GREETING
to edit my features. But what is 'GREETING' here?
I tried with my feature name, but it didn't worked. It's also not mentioned in the documentation either.
Please help me out if someone has used this.
I am using the below dependency
<dependency>
<groupId>org.togglz</groupId>
<artifactId>togglz-spring-boot-starter</artifactId>
<version>2.6.1.Final</version>
</dependency>
PS: I know about the console, but I don't want to use the console, I have to use the endpoint only to toggle the feature.
The actuator endpoint only allows you to change the state (i.e. true or false) of an existing feature by that same name. See the code's comment and implementation: https://github.com/togglz/togglz/blob/2.8.0/spring-boot/starter/src/main/java/org/togglz/spring/boot/actuate/TogglzEndpoint.java#L63

Unable to display index.html in jax rs with spring boot

I am trying to create a simple app with jax rs, springboot, angular.
I have placed the index.html in static folder, but while hitting the url localhost:8080/index.html or localhost:8080 it's throwing 404 not found error through the custom exception handler. I have added index.html as welcome-file-list.
I have a controller class but i have not written any specific method to handle it.
Also i want to display error specific page with message details.
Definitely i am missing something but not getting any pointer to find it out. Please help.
Do i need to configure web.xml explicitly for this?
Add
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
To your pom.xml file, spring boot auto configure all the rest.
I know this is older, but to expand on Itsik's answer I found this answer via this other answerto be very helpful in explaining this.
Summed up, if you want to be able to serve up resources/static/index.html AND use JAX-RS/jersey for api endpoints, include both spring-boot-start-web and spring-boot-starter-jersey. In your JerseyConfig add #ApplicationPath("/api") or whatever subpath you want all your jax-rs rest endpoints to live under. Then you will be able to have the best of both worlds.

Forwarding request to a JSP

I discovered Guice last week... I'm trying some easy tricks with it. However, I'm currently blocked...
I'm trying to forward a request to a JSP in a Servlet served by an url-pattern which contains a " * ". But I receive "Error 404" all the time :(
Step by Step :
ServletModule :
serve("/test/*").with(TestServlet.class);
TestServlet :
public void doGet(HttpServletRequest req, HttpServletResponse resp)
{
System.err.println("Start");
try
{
req.getRequestDispatcher("/WEB-INF/layout/test.jsp").forward(req, resp);
}
catch (Exception e)
{
e.printStackTrace();
}
}
I get this error :
HTTP ERROR 404
Problem accessing /WEB-INF/layout/test.jsp. Reason:
/WEB-INF/layout/test.jsp
I tested with "serve("/test").with(TestServlet.class);" and it worked
I tested without Guice (by defining servlet in the web.xml) and it worked...
What did I do wrong?
Thank for reading!
Client can't access resources from Web-INF directly (by url). So forwarding doesn't work in this case. But your servlets can. So just use include instead of forward.
There's a good chance you didn't do anything wrong at all. There is a bug in Guice, arising from their mishandling of Include and Forward attributes against servlet standards, as described here...
http://code.google.com/p/google-guice/issues/detail?id=647
The upshot is that the receiving servlet is misinformed about the path, and hence requests to load resources do not find their proper target even if they are specified correctly and even if the same code works when using web.xml (which is interpreted by your servlet engine and not by Guice).
I'm endlessly puzzled why this doesn't act as a dead-end for many many projects in Guice, so perhaps there's something in the behaviour of other servlet engine configurations which masks this error. I'm using Jetty launched explicitly in Java using Server#start(); and it is a deal-breaker for a lot of server logic.
However, the Guice team seems to have been studiously ignoring the bug for a long time, even when a patch was provided to them against v2.0. What they need is a test-case written against their SVN build but I've never succeeded given all the work needed to create stubs which emulate the servlet engine and so on.
The problem has been partially fixed in guice and guice servlet 3.1.1 with one problem still taking place:
When mapping a servlet using the asterisk pattern '/*' as below:
serve("/myservlet/*").with(MyServlet.class);
And have MyServlet.java forward to a jsp page, then the forward() will only work if the jsp page has no underscores (So, myservlet.jsp will work, my_servlet.jsp wont work).
// This WORKS
req.getRequestDispatcher("/myservlet.jsp").forward(req,resp);
// These DONT WORK (any file having _ or - characetsrs wont work)
req.getRequestDispatcher("/my_servlet.jsp").forward(req,resp);
req.getRequestDispatcher("/my-servlet.jsp").forward(req,resp);
req.getRequestDispatcher("/WEB-INF/myservlet.jsp").forward(req,resp);
Now this explains why WEB-INF forwarding does not work for a servlet mapped with /*. The reason is that WEB-INF contains a dash character which for some reason is creating a problem for guice servlet.
When trying the example above, make sure to rename the file myservlet.jsp to my_servlet.jsp when trying the cases to verify the case above.
I have no idea why this weird case is taking place.
NOTE: I'm using Tomcat 6.0.35
To have Guice 3.1.1 add these to your pom.xml
<dependency>
<groupId>org.sonatype.sisu</groupId>
<artifactId>sisu-guice</artifactId>
<version>3.1.1</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>org.sonatype.sisu.inject</groupId>
<artifactId>guice-servlet</artifactId>
<version>3.1.1</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>org.sonatype.sisu.inject</groupId>
<artifactId>guice-assistedinject</artifactId>
<version>3.1.1</version>
<scope>compile</scope>
</dependency>
Or you can download the jars from:
Guice Servlet Jar
http://repo1.maven.org/maven2/org/sonatype/sisu/inject/guice-servlet/3.1.1/
Guice Jar
http://repo1.maven.org/maven2/org/sonatype/sisu/sisu-guice/3.1.1/

Spring MVC REST : static files unaccessible because of url-pattern

My Spring Dispatcher servlet url-pattern is /* (as spring MVC REST suggests)
Now all the request are resolved by this Servlet. even CSS/JS/Images also get resolved and handled by servlet..
So, Spring MVC tries to find controller.. :(
How to bypass this? Is there any standard way out of this problem??
& Don't want to change url-pattern to /rest/* (so, other static resources get accessed by /css/ or /js etc.)
You can map your controllers to a smaller set of URLS (i.e. /app/*), and then rewrite the URLs that your users actually see so that they don't even know about. Have a look at the mvc-basic webapp sample, particularly web.xml and urlrewrite.xml to see how this is done.
Map the Spring dispatcher to some subsection of the URL space, and use Tuckey to rewrite URLs the user deals with.
http://www.example.org/app/controller/action -> http://www.example.org/controller/action
Just a heads-up update on this: the default rewrite configuration as defined in the Spring sample did not work out of the box for me. The rewrite rules for stylesheets, scripts, etc. were still processed to the /app/* rule, and subsequently handled by the DispatchServlet, which is not desirable.
I had to add the last="true" attribute to the styles/scripts/images rules to indicate that other rules should not apply, and I had to use the FreeMarker Spring URL macro in any CSS/JS include paths.
Just in case someone encounters the same problem.

Combining namespace based configuration with different authentication methods in spring-security

I'm trying to get spring-security to work with a project where there is both a form login component needed (for website access) and a http-basic or http-digest component for web services. Now we started out with the namespace based configuration, e.g. a spring-security.xml file with stuff like:
<http auto-config="true">
<intercept-url...>
...
</http>
But you have to go with form-based as default or http-basic as default (i.e. this only configures one filter chain). What I want is for some stuff to never redirect to a form and just use http-basic or equivalent. The manual does seem to cover this, only if you follow their advice, you'll end up having to define own filter chains for everything.
So I was wondering, is there really no other way? Is there perhaps a way I can reuse the filter chain introduced by the http element for those elements that can still use the old scheme? The namespace based config is really handy for us since it's easy to read and understandable, whereas a list of bean definitions is less so...
This is on the Spring Security roadmap. See issue SEC-1171.
I'll answer this myself as nobody seems to be going to. It seems the answer to this one is "no", I'm now using an almost entirely beans based config. Answers that contradict me are always welcome of course. :-)

Categories