Is there a way to only allow POST requests to j_security_check? I want to reject GETs.
I am using Form Based security and want to only allow Posts to j_security_check. If a login request is made via a GET, the request should be rejected.
Having been trying to do the same on a JBOSS(Tomcat) server due to security concerns of JAAS using GET methods I attempted various ways.
Using a web.xml security constraint on the url pattern /j_security_check to only use POST - This doesn't work for JAAS mechanism as it would for normal servlets.
Passing login details from the login page to an intermediate servlet which checked the request method and if not a GET then forwarding on to j_security_check. - This did'nt work and was over complicated.
Creating a Filter that would check the request method and only invoke on a POST message to j_security_check - This didn't work as JAAS is deeper in web container and is called before the filter mechanism.
Creating a Valve, which DOES get called before the JAAS.
By adding the following in the invoke method:
HttpServletRequest req = (HttpServletRequest) request;
if (req.getMethod().equals("GET")) {
log.warn("Someone is trying to use a GET method to login!!");
request.getRequestDispatcher("/login.jsp").forward(req, response);
throw new ServletException("Using a GET method on security check!");
}
This does work.
Yes you can reject the GET request. In the web.xml file in the security constraint section you can specifiy the http methods allowed. In the following xml the only method allowed for this security constraint is the POST method. j_security check will only allow the post method.
<security-constraint>
<display-name>Your security constraint</display-name>
<web-resource-collection>
<web-resource-name>Your resource name</web-resource-name>
<url-pattern>/The URL pattern</url-pattern>
<http-method>POST</http-method>
<web-resource-collection>
<security-constraint>
You would need to rephrase your question.
j_security check is typically used in the login page.
If you request a secured resource and you were not authenticated, you are automatically redirected to the login page (assuming the app is configured to use Form Based security)
If your resource should not be challenged for GET requests, follow what Doug has mentioned. For example, if you want to secure POST calls to myaccount (the pattern for a Servlet) then you would be redirected to the login page only when a HTTP Post is made while the GET request would be accepted even without a user authentication.
The implication is you want to allow authenticated users access to POST request while GET requests are permitted to everyone.
An alternative approach I am considering to implement:
Blocking all but POST requests to j_security_check in a reverse-proxy/loadbalancer like nginx/apache
E.g. on Apache 2.4 this works:
<LocationMatch ".*j_security_check">
AllowMethods POST
</LocationMatch>
If I would need more customization I could reimplement j_security_check with my own servlet using HttpServletRequest.login(...)
Related
I'm trying to make a webapp that will run on a single HTML page that will allow users to interact with the server through JavaScript and ajax. I'd like to make my requests safe against csrf attacks by including a csrf token in each request.
Because my webapp will only be operating on a single page, I can't use the ${_csrf.token} (or something like that) syntax in the view because the view is going to be a json object. Instead I'd like to have a url like "/security/csrf" that returns a token associated with the user's session. (Yes, this won't be a restful service exactly.)
Is there some way for me to generate a csrf token that Spring Security will be able to access when verifying a log-in? And additionally, is there a flaw in using csrf tokens in this way?
Token per request will kill caching. Token per session is just as safe.
In your first html response, include the csrf token in a meta tag, like the docs say: http://docs.spring.io/spring-security/site/docs/current/reference/html/csrf.html#csrf-include-csrf-token-ajax
You can use the same token across requests (in the same session)
I have an Apache proxy which redirects requests to /foo/bar to a web app running on /foo. The problem is that I have a Servlet filter in my filter chain which requires the request to still be in the /foo/bar format. It is an authentication filter I can't change and this is resulting in incorrect redirects after login to /foo instead of /foo/bar.
Following other similar threads, I've attempted using RequestDispatcher.forward with a modified request and HttpServletResponse.sendRedirect to modify the URL. The first approach seems to skip the rest of my filter chain, and the second goes to the proxy which then modifies the URL back to /foo.
Is there any way around this. Ideally what I'd like is for just the authentication filter to get a /foo/bar request and the rest of the chain to get a /foo request.
Looks like HttpServletRequestWrapper was what I was looking for. Just needed to extend this and provide getRequestURI and getRequestURL overrides (rather like described here). Then needed to add filter mappings before and after my auth filter to convert the request URL/URI as needed.
I am writing a Restful webservice method,which require authorization first...
such as a findItems method..which need username and password in Http Authorization
the sample code:
#GET
#Produce(MediaType.APPLICATION_JSON)
public String findItems(){
...
}
how to verify the http authorization before the method excutes...
I use a user-type and role-type control with a basic JAAS authentication. After authentication, the client makes http GET requests to the REST web service. In my Facade get method, I inject the #Context SecurityContext as input parameter, and use if for user / role identification in order to provide the correct answer to the GET request, depending on the user's role.
See here for an example of what I mean:
Using JaaS with Jersey on Grizzly
you can use Filters so you can check the authorization
I went through a similar question here. But I am yet not clear over concepts. Here is my scenario...
My client (a mobile device app) has a login screen to enter username, password. After submission, he should see the list of books in the database plus the list of books subscribed by that user.
I am having a /LoginService which accepts username, password & checks a mysql database for credential validation. Only after authorization....I have a /BookService ; GET on which returns all the books in database.
Should I use GET, POST or PUT on my loginservice ? Since a login request is a read-only operation, I should use GET - but this sounds stupid for browser(as the submitted data is visible).
What are accesstokens (mentioned in the linked answer above), and how to generate them using Java ? I am using Jersey for development. Are they a secure way of authorization ?
Thanks !
As far as I understand you are trying to implement stetefull communication between client and server. So you login with first request and then use some kind of token to make further requests.
Generally I can recommend you to have stateless communication. This means, that you authenticate and authorize each request. In this scenario you don't need LoginRestService. Important points here are:
Client can provide userName and password through HTTP Headers (non-standard, something like UserName: user and Password: secret).
At the server side you can use
Use AOP: just wrap you BooksService with AuthAdvice (which you should write yourself). In advise you access somehow (with Jersey functionality) HTTP request, take correspondent headers from it, authenticate and authorize user (that you load from DB), put user in ThreadLocal (so that it would be available to the rest of your app) if needed and just invoke correspondent method or throw exception if something wrong with credentials.
Use Jersey functionality: (sorry I'm not very familliar with Jersey, I'm using CXF, but conceptually it should be the same) just create some kind of AuthHendler and put it in request pre-processing pipeline. In this handler you need tho make exactly the same as in AuthAdvice
Now each of your request would be authenticated and authorized when it reaches BooksService. Generally stateless implementation is much better for scalability.
If you want to go statefull way, than you can just use HttpSession. LoginService.login() should be POST request because you actually making some side-effects at the server. Service will perform authentication of your user according to provided username and password and put loaded User object to session. At this point, the server side session is created and client has session ID in the cookies. So further requests should automatically send it to the server. In order to authorize requests to BooksService you still need some kind of Advice of Handler (see stateless solution). The only difference: this time user is taken from the HttpSession (you should check that you are logged in!).
Update: And use HTTPS! :)
I've got nothing to dispute in Easy Angel's answer, but got the impression you'd like some additional comment on the concepts too.
The problem is clearer if you think in terms of resources rather than services. Think of your proposed login as generating a new authorization resource, rather than querying a login service. Then you see that POST makes perfect sense.
The authorization token would be a key for your user into the session object (as explained in EA's answer). You'd probably want to generate it by concatenating some information that uniquely identifies that user and hashing it. I certainly agree that a stateless authentication method would be preferable, if you're aiming to get all the benefits of REST.
Use what is available in HTTP: HTTP AUTH over SSL.
Protect all your resources with HTTP AUTH and the browser will take care of providing a login for the user.
If you need session information on top of that, use cookies or a session parameter.
Cookies were made for exactly these kinds of purposes and usually work well.
I want to filter all requests to my web application through my "SecurityFilter" which checks that a session variable "authToken" is valid. The problem is that in order to get this token you need to hit the "AuthServlet" which is at /auth.
I need to filter all servlets except the /auth servlet with my "SecurityFilter". How can I do this via guice-servlet?
I thought of trying to no avail...
filterRegex("!((.)*auth(.)*)").through(PortSecurityFilter.class);
^((?!/authorize).)*$ worked.