Spring Security - Anonymous Authentication - HttpSessionRequestCache - java

Please help me on this.
void setCreateSessionAllowed(boolean createSessionAllowed)
method of
org.springframework.security.web.savedrequest.HttpSessionRequestCache
class says
If true, indicates that it is permitted to store the target URL and exception information in a new HttpSession (the default). In situations where you do not wish to unnecessarily create HttpSessions - because the user agent will know the failed URL, such as with BASIC or Digest authentication - you may wish to set this property to false.
So I did not understand the description properly, also we are using a product and its documentation says setting it to false will disable the creation of anonymous user sessions.
So my question is, session creation and associating it with a request is servlet container's job. So How come using this method(setCreateSessionAllowed) will not create a session.
Please validate my understanding, is it correct or not. also
setCreateSessionAllowed(false), will JSESSIONID be created or not?

The HttpSessionRequestCache saves the last URL requested by the client in a user session.
This is used by spring security, when it redirects you to a login page, to restore the url after a successful login.
In case of basic or digest authentication is directly authenticated or asked to resend the request with the credentials. Therefore URL caching is not necessary.
If setCreateSessionAllowed is set to true, it will by default create a session to store the last url.
If set to false it will only support this feature if a session is already is created.
If no url is stored, spring security will use the default target URL supplied in the spring security configuration.
As for your last question, it is not directly obvious to me how it will affect the anonymous login feature of your mentions product.

Related

Session management using spring security

I have created a basic spring security authentication using UserDetailsService and now I am able to validate user. However, I don't understand how to achieve below things:
Once a user is logged in, when next request comes how and where do I check if the request is coming from the same logged in user or other logged in user?
I know the concept of Spring interceptors where I can intercept all incoming request. But is there something in spring security that does this?
How can I start a session after logging in and store values in session for that user?
I browsed through existing answers but most of examples are for logging in.
I would appreciate if someone can give me examples.
EDIT:
I think I should use session scoped beans in order to maintain user's session contents rather than manipulating httpsession directly.
I think you really need to spend some time reading the Spring security documentation and over all JSP, servlet and MVC architecture. You have several misunderstandings,
After authentication, you don't need to start a session it was already there when the request came. Remember request.getSession()we get the session from the request and I am really NOT aware of any other way i.e. instantiating session object and assigning it to request/response. After successful authentication spring automatically sets a SPRING_SECURITY_CONTEXT attribute in session and this variable is later used to determine whether user is already authenticated or not (Spring does that for you, you don't need to use this attribute).
In spring security we set an authentication entry point which has information about login page url and FORM_LOGIN_FILTER which has information about login processing url, login success url and login failure url among few other things.Every request whose session doesn't have SPRING_SECURITY_CONTEXT and auth attribute gets redirected to login page url.
I could give the code directly but it would be great if you read at least few pages of Spring documentation here. Once you understand the concepts and are still not able to solve the problem. Edit your question with detailed problem and we will try to fix it.
At first you need to create an Authentication object using current HttpRequest as below:
public class SessionService{
public Authentication getSession(HttpServletRequest request) {
HttpSession session=request.getSession();
SecurityContext ctx= (SecurityContext) session.getAttribute("SPRING_SECURITY_CONTEXT");
Authentication auth=ctx.getAuthentication();
return auth;
}
}
Then, you can retrieve the session details from this Authentication object by passing the current HttpRequest as follows:
Authentication auth = sessionService.getSession(request);
The above auth object contains the details that you need.

Spring Security: Different authentication methods depending on entity

first post here, hope im doing right.
In a project, we have a scenario where we have a single web application with multiple entities. Currently, the login is managed via default JDBC Spring Security provider, working fine.
For a new requirement, we need that each entity can have their own login method (currently 2 methods would be available, the JDBC one, which is the current one, and the second method would be authentication via SAML, with each entity defining their own IdP, but this is another story)
I need some guidelines on how this can be achieved, I have done some search and I have found providers for different URL's, etc... But not different login methods for the same app and url's depending on the user type or entity.
Is a good approach to have a custom single entry point where we can check the entity user and then use the suitable authentication provider?
Kind regards,
Alex
As each of your users might be using a different IDP you will in any case need to determine the username before proceeding with initialization of the authentication process - but you already know this.
One approach to take (similar to what Microsoft is using with the Office 365 for corporate users) is:
display a login page with fields for standard username + password
once user enters username and blurs the input field, you make an AJAX call (to your custom API made for this purpose) and fetch information about authentication type + IDP to use for this user
in case the type is password you simply let user continue with filling in the password field and POST to the same place as you're used to for processing with the JDBC provider
in case the type is federated authentication you initialize authentication with the correct IDP by redirecting to /saml/login?idp=xyz and continue with the SAML flow
It's possible to avoid any APIs by submitting the form once user enters the username, or let user click a "Continue" button. It would then make sense to use a custom EntryPoint which:
redirects user to the main login page in case it wasn't provided with a username
displays either login page with username/password or redirects to the correct IDP, once username was provided

Filter for checking session existence

I am developing a web application in Struts. I have a requirement that I have to check that a session exists for user. If the user session exists then user can access the resource, or I need to check session variable existence before accessing every JSP page.
For that I make use of filter where I check for the session variable existence. But when I use filter, every request is routed to that filter--even the login page request is routed to filter. The login page doesn't need the filter check applied, what to do for this?
This is typical session filter use case. For login page request, not to be filtered, you need have a different URL for login page which will be excluded in the URL mapping for the filter.
OR
In the filter itself, you can check what is the requested URL, its login page then don't check for the session. But I would recommend the earlier approach because its rightly address the Separation of Concern philosophy.

Seam security with externally-orchestrated SSO

I have an application deployed on WebLogic 10.3.2 (11g), in which the user logs in through SSO. In other words, if the user is not logged in, he is redirected to SSO, where he logs in, and then is redirected back to the application. The whole redirection takes place by an the Oracle HTTP Server (a modified apache), which makes sure that only SSO-authenticated users can see the applciation.
So, when the user finally sees the application, he is already logged in.
Is there a way to use Seam security with this scenario? What I would like is to use the roles of the Subject to restrict access to certain pages and components.
A way I thought of, but for which I am not sure, is to use the subject that is populated by the SSO authentication provider of WebLogic, and use it to populate the Identity component of Seam. That would take place in the authentication method, which will always return true (since the user is already logged in). Inside the method, the credentials and roles of the Subject will be "transfered" inside the Seam identity.
Is this feasible at all?
Cheers!
You could write your own authenticate method, or override the Identity class and the login() method to achieve this. I've done something similar with a reverse proxy that performed our authentication. In the scenario, the proxy sent back the user ID of the authenticated user and all the groups they were a member of as header values. I wrote a filter to intercept the headers and then used my custom Identity class to do the rest.

Java EE Authentication Error Handling

We are currently trying to implement a web application which is using the Java EE authentication mechanism with a FORM-based login, inside the Websphere 6.1 web container. If the authentication is successful, we have everything working; the LDAP membership groups are being retrieved, the group to role mapping is being performed, and the roles are being returned to and correctly interpreted by the web application.
If the authentication is not successful, the form-login-error page is being returned. However, this is a static page that simply says something like "there was an error". How do we trap the specific error that prevented the successful login (username/password incorrect, LDAP repository unavailable, account locked, password expired, etc.)? It seems like there should be some easy way to do this, as you would want to treat some "security" exceptions differently than others.
I use Struts so it will do forwarding for you. If you don't have a framework (why not?) you'll will have to do it manually.
The Java EE spec covers the j_security_check servlet.
The login page POSTs j_username and j_password to the j_security_check servlet. Your app will be configured to error to an unauthorized page (see web.xml) but will (initially) call a servlet. 401 or 403 will go to a forbidden page (again web.xml)
Inside that servlet (which extends the HttpServlet) - you will check for all that good stuff.
public final void doGet(javax.servlet.http.HttpServletRequest request,
javax.servlet.http.HttpServletResponse response)
throws javax.servlet.ServletException, java.io.IOException
{
// initialize the app
AppInit initializer = new AppInit();
// get the logger
log = new Log4jWrapper(this.getClass());
// initialize the application session
HttpSession sess = request.getSession(true);
sess.setAttribute(CommonConstants.SESSION_CURR_USER_ID, request.getRemoteUser());
// initialize the JSP to forward to based on the user role
String fwdJSP = "SetupMainPage.jsp";
if (request.isUserInRole(CommonConstants.ROLE_MANAGER)) {
log.debug("User is a Manager");
}
//else other role checks - (these are users in groups in the LDAP)
// initialize the application session and set a variable to indicate that
// we are coming from a first time login (not a timeout login)
sess.setAttribute(CommonConstants.SESSION_COMING_FROM_INITIAL_LOGIN,"TRUE");
disp = getServletContext().getRequestDispatcher("SetupMainPage.jsp");
disp.forward(request, response);
}
//else failure
Unknown user
[11/22/08 8:54:47:993 EST] 7f6ac69c FormLoginServ E SECJ0118E: Authentication error during authentication for user s
right user - wrong password, but the request.getRemoteUser() will have a value
[11/22/08 8:56:45:082 EST] 7f51469c FormLoginServ E SECJ0118E: Authentication error during authentication for user jbsymolo
Unfortunately - i don't have any examples of someone locked out but I going to assume that the main security directory (LDAP) you will have an entry for the user for that.
This is from someone else (so I can't take credit)
I think this page describes how to do what you want to do.
Specifically how to retrieve the authentication exception from an arbitrary underlying authentication source (looks like Websphere calls them user registries).
Throwable t = com.ibm.websphere.security.auth.WSSubject.getRootLoginException();
if (t != null)
t = determineCause(t);
Where determineCause() is defined on the same page. This way, even if your server is configured to authenticate against a John Deer tractor, you will have access to the "OutOfGasLoginException" if there is one. The above code can go into the Servlet, Servlet Filter, or JSP that is redirect to by the container (as described above by jsymolon). It simply examines the exceptions and then places a corresponding friendly error message on the resulting page.
This is ancient knowledge - I believe to have done such a thing with tomcat. There was, as far as I can remember, no standard way, as the implementation was completely decoupled from the request and frontend web stuff, so that it was difficult to establish any means of communication between the authenticating component and the frontend (e.g. error page).
We ended up with a tomcat specific way, relying heavily on the current implementation. I'm no longer with that company, so I can't tell about the current state of the code or the solution we chose back then. I believe you'll also have to have some Websphere specific solution - be it the use of thread local variables, keying messages with the username that attempted to log in, somehow getting hold of the session identifier or similar.
Check this article Securing J2EE Applications with a Servlet Filter. I believe it covers your requirement to be able to pass the reason for the authentication error.
The JavaEE specification does not provide a standard mean to get an authentication feedback like error codes.
According to the following IBM Redpaper about z/OS security integration in gray note on page 57: IBM specific extension is available so that the error page JSP can report a specific message (like password expired) based on an error status code.
According to the WebSphere InfoCenter the FormLoginWeb sample from the TechSamp package in your WebSphere installation (samples/src/TechSamp/FormLoginWeb) is supposed to demonstrate such IBM specific extension but... The only thing interesting is the LoginFilter that intercepts calls on /j_security_check and is able to do pre-login validation and post-login action as explained in details in that paper.
With such a mechanism it is possible to get login exception from JAAS Subject and set an login error code in HttpSession so that the error page can generate a specific message.

Categories