Java Servlet security manual authenticating a request server-side - java

I have a java servlet serving a website content and it is using forms authentication to login the users and let them access the content. Whenever the user access a protected resource he is redirected to a login form which is used to post the username/password to the j_security_check path in the web server. The rest is handled by the java security mechanisms which generate the user session, respond back and redirect him to the initial resource he tried to access. So far so good.
What I want to do, is provide access to the resources for non-logged in users in the following way: GET www.myserver.com/anotherLoginMethod=aasdfJKL where aasdfJK is a hash generated by the server. The server keeps an association of that has with a user account and when the user sends this GET request I need to:
1)Get the anotherLoginMethod parameter value.
2)Retrieve the associated user account ( credentials ).
3)Login the user automatically as if he was doing a POST with his username/password at j_security_check handler.
Is that possible ?
I tried using HttpServletRequest's login and authenticate methods in a Filter but with no success so far.

It is relatively simple. You need to decide
1. Where do you intend to keep the hash values and its association to the user?
2. How do you propose to give the hash to the user? Ensuring security is paramount for this step.
Once you have done this you can write a servlet filter which can intercept this request or you can have the logic in the servlet itself, get the user which is associated to the Hash value, generate a session as if the user has logged in successfully and redirect to the required URL. It is important to understand the security issues associated with such a methodology.

Related

Authorization code flow - how to get Code parameter value

I've implemented an application that redirects to the wso2 identity server login page. If the login is successfull the user is redirected to a page where he can read his profile details.
Based on his role he can perform certain action, like create a new user.
I've implemented an API (http://localhost:8080/add-user) that calls this URL ( https://localhost:9443/t/carbon.super/oauth2/token) to generate the access token with the desired scope (for example internal_user_mgt_create) that I need in order to call
the wso2 SCIM2.0 API (https://is.docs.wso2.com/en/latest/apis/scim2-rest-apis/#/Users%20Endpoint/createUser).
Everything works if I use grant_type=password and I use the user credentials to generate the access token to call the wso2 SCIM2.0 API, but I want to use "authorization_code" as grant_type to avoid sending user credentials in my application.
How can I do that? And I know that one of the parameters that I need to use this flow is "code", where can I get its value?
You can configure authorization code grant in your application by selecting the Code from the Allowed Grant Types list OAuth/OpenID Connect Configuration in your application. [1]
When using the auth code grant your application needs to wso2 authorize endpoint to obtain the authorization code Using this authorization token and client secret you can obtain the access that is capable of calling the scim endpoint.
Refer to following documents for more information
[1]. https://is.docs.wso2.com/en/latest/guides/access-delegation/authorization-code/
[2]. https://medium.com/identity-beyond-borders/generating-access-tokens-using-wso2-identity-server-4d8c084a3bf5
It's harder to provide an exact answer to this question without knowing more details about the app and the flow you'd expect your users to go. However, it'd be much easier if you have a better understanding of the OAuth2 code grant type. The following is the basic flow.
The user accesses your application through a web browser.
Your application redirects the user to the identity server, with the following parameters in the request.
client_id=xxx
response_type=code
redirect_uri=yyy - Location in your application where you want to get the authz code. This needs to be registered with the IS service provider beforehand.
scopes
The IS prompts the user to log in.
The IS then redirects the user to the given redirect URI, with the authorization code.
Once the code is received by the client, it makes a back channel call to the token endpoint of the IS (https://localhost:9443/t/carbon.super/oauth2/token) with the following parameters.
grant_type=authorization_code
client_id=xxx
client_secret=zzz
code=ccc
IS validates the code and issues an access token.
Read more on OAuth2 here.
Now, if you're getting the "Inactive authorization code" error, your application might already be calling the token endpoint with the code received, before you call your add-user API.
Ideally, your add-user API shouldn't call the token endpoint at all. You should call the token endpoint from your application, get an access token and pass that to the add-user API if needed. Or you can directly call the SCIM API from your application itself.
I hope this helps!

How to fix User Impersonation in Java Web Application?

I have java web application using struts 1.x. Recently my application has gone through penetration testing and our testers found some security holes. Let me explain. In my application i have 2 users called ‘Admin’ and ‘user’. First our PenTester logged to my application as ‘Admin’ and they use ‘Burp tool’ to intercept the request and copy the whole request content into notepad and then forward the request. Now My application log in as ‘Admin’. They use another browser instance to login as “user” and use burp tool to intercept the request. This time they removed the whole request content and copy back the whole request content of ‘Admin’ and then forward the request. Now my application logged in as ‘Admin’ without asking any user id/password? How to restrict this situation? I already stored userid in my session variable after successful login of each user. The moment they intercept the request and copy the ‘admin’ request content, my session variable userid also changed to ‘admin’. How to validate this situation? Your help is really appreciated.
That is not really that much of an issue since the first part "copy the whole request content" is not easily doable if you have a proper HTTPS / SSL connection. That only works if the PC the user is logged in on as an admin is compromised in which case: nothing you can do about it anyway because they can just sniff the keystrokes and get the plain password.
If on the other hand you communicate without the S, namely just HTTP then the solution is: get a certificate and switch to HTTPS.
Apart from that your application can pin a session to an IP which means if the session id / cookie is stolen and someone else uses it you can detect an IP mismatch and ask for credentials again.
To prevent direct replay attacks like copying the request and sending it again you can introduce a hash that incorporates the timestamp or alternative measures, see. How do I prevent replay attacks? . The problem however is that copying the entire request means copying the cookies as well and if the "admin" cookie is copied this measure will not prevent you from "generating" a new hash based on the now admin user.

Alternatives to Basic Authentication when logout is required?

If BASIC authentication was not build to handle logging out, what alternate authentication methods exist for authenticating backend services that need to be able to log out?
I found these references stating that BASIC auth is not able to do log
out without some hackiness:
How to log out user from web site using BASIC authentication?
How do I log out?
We are using BASIC authentication to log into backend applications, and FORM authentication for frontend applications. After our team tested the stack on FireFox/IE, it was found that a user would not be able to log out if they logged into the backend services via BASIC authentication on those browsers. The hacks and workarounds are unacceptable to my team (asking user to enter incorrect credentials, making user close browser, use javascript to send incorrect credentials, ask user to clear browser cache, etc), so we are seeking advice on alternative authentication methods that DO allow logging out
EDIT- My temporary workaround for logout:
I am currently getting around this problem by using FORM authentication. One problem is that my backend services rely on the shared frontend login.html form, and another problem is that Postman does not support logging in via a redirected FORM input, and our client Arquillian calls blow up from the login form.
FORM authentication gets rid of the "I can't log out with BASIC" problem, but now I can't authenticate as straightforwardly.
Form based-authentication
If it's okay to keep the session state on the server, you can go for form-based authentication.
Send the credentials in the form, if the credentials are valid, the server will issue a cookie that will be sent back and forth to identify the session on the server. To logout, the session can be invalidated:
session.invalidate();
You also can configure your application to expire the sessions due to timeout:
<session-config>
<session-timeout>60</session-timeout> <!-- minutes -->
</session-config>
Token-based authentication
If you want a stateless mechanism, go for token-based authentication.
The client exchanges hard credentials (such as username and password) for a piece of data called token. For each request, instead of sending the hard credentials, the client will send the token to the server to perform authentication and then authorization.
For the token, you could use JSON Web Token (JWT). It's an open standard that defines a compact and self-contained way for securely transmitting information between parties as a JSON object.
JWT is a generic name for the following types of token:
JSON Web Signature (JWS): The payload is encoded and signed so the integrity of the claims can be verified.
JSON Web Encryption (JWE): They payload is encrypted so the claims are hidden from other parties.
The image was extracted from this page.
The token can define an expiration date in the exp claim. For logout, you can remove the token from the client.
You also could keep the track of the tokens in a whitelist on server-side and invalidate them as you need. There's no need to store the whole token on server side though: Store only a token identifier in the whitelist and use the jti claim to store the token identifier in the token.
I suggest you to have a look at Apache Shiro, especially the way session are managed (https://shiro.apache.org/session-management.html).
They have namely abstracted the concept of session so that it can work in various situations: in a webapp (in such case, it's simply a wrapper around the HTTP session), in a standalone app, etc...
In your particular case, the front-end could open and close (logout from) a Shiro session that is shared with the backend layer.
See the sentence:
Heterogeneous Client Access
(...)
For example, a (desktop) application could ‘see’ and ‘share’ the same physical session. We are unaware of any framework other than Shiro that can support this

Token based login and authentication in java

I want to know how the token based authentication is done in Java. I want that if I hit my application then the system should redirect it to the login page and once the user enters the credentials, the user shall be validated and authenticated. Once authenticated a token should be generated which shall be handled across client and server. My concern is if the token is generated, how it is being passed to the client and how the client sends it back to the server on every request processing. I know that it has to be set in header. But my question is how exactly. I know we have spring and all but I want to know how it is being done using jsp and servlets.
I went across few websites but unfortunately could not find the expected result. A small demonstration shall be very helpful. Thanks in advance.
There is no such authentication token. There is a session token defined in J2EE Web Application server standard (https://docs.oracle.com/cd/E19644-01/817-5451/dwsessn.html). Once the JSessionId is established between server and client it is used to manage the user.
For example if you build you own authentication system you can bind the jsessionid with user login attempts, and keep a list of jsessionids which has logged in successfully. This is basically what authentication frameworks do.
Also, you can check this Under what conditions is a JSESSIONID created? and this: Spring security FAQ

How can I ensure an http request comes from specific user?

I am writing an additional service for a website, which utilises the existing login behaviour, while requiring some additional signup details from the user. The new service runs in a different subdomain.
The user will be able to create resources on my data web app, which must be saved against that user's data collection.
I expect that this user identifier will be passed to the webapp in the body of the http request. However, I am concerned that a malicious attack could rewrite the user name in the body to make requests appear as if from another user.
What can I do to make this safer? (And does this count as a CSRF attack?)
The new service is written in Java, with Spring 3.
You can never ensure an http request comes from a specific user, you can only attempt to validate a user and a request. Usually this is done by creating a ticket during the login or authentication process, then requiring that ticket on subsequent requests. You can then match the ticket with the user and accept that as valid. The ticket expires after a period of inactivity, requiring the user to login again.
You should pass the requests through the same security stack that the main website uses if at all possible.
If it isn't possible, I would use Spring Security to handle the authentication. I'm not sure what plugins already exist for Spring Security for authenticating service requests like that, but you could always require that a cookie be used for the session, and then it's just a matter of the client dealing with the authentication steps.
So, you could use a "normal" form logon, or you could put together a token request setup, but that is much more involved.

Categories