I use Seam 2.2.1.CR1 on Weblogic 10.3.2 (11g). I want to use an external SSO (the proprietary one Oracle provides, based on OID). I would like to integrate this external login (the login screen belongs to the SSO). Please note that I don't want to use an LdapStore. If I got this right, this would require me to have a login page through my application, which would then somehow connect to the LDAP and login. I want to use the external login screen provided by the SSO.
SOME THOUGHTS
I don't see the procedure of using this SSO to login to be any different than using any Authenticator of WebLogic. Both with the SSO and with the BASIC authentication on the Default Authenticator, the application-wise result is the same: the user enters the application and on each HttpServletRequest the method getRemoteUser() returns the username with which the user logged in (either on the SSO or the BASIS login), and the .isUserInRole('blah') returns true/false depending on the roles assigned through the authentication. So, I see the two authentications to be exactly the same, programming-wise.
THE QUESTION
My question concerns how this can be integrated with the Seam Security. Seam in Action explains how a custom login screen can be included in the application, which populates the Identity component and the Credentials components. Seam then uses these components to apply the high-level security restrictions, like s:hasRole.
However, in my application I DON'T want a login screen. All I want is to be able to somehow use the Seam Security with what I already have: The roles and username in the HttpServletRequest.
I have found this thread (See at the end), but I am not sure I quite understand. A question, for instance, is if extending the Identity is what I need.
Another question is that in Seam in Action Dan Allen says that having a login page is mandatory, which I don't want to have. From page 449:
Only Seam isn’t going to know where to
direct a nonauthenticated user when
this page is requested because you
haven’t specified a login page. If a
login page hasn’t been set, Seam
throws a NotLoggedInException.
Generally, I think that integrating an external SSO (or any Application Server authenticator) with Seam is still poorly documented, although it is a very common business requirement. I guess we'll all hang in until the guys finish with Seam 3.
Meanwhile, any general / specific directions?
Cheers!
-- http://seamframework.org/Community/HelpWithIdentityloginAndAcceptExternallyAuthenticatedPrincipal
It works with Seam 2.x.
Create a fake login view page in pages.xml. Then, use it with an or similar to login externally.
Then, add a navigation rule to redirect to success/failed login pages in that navigation view.
And you will need to override the authentication method.
Something like this:
<page view-id="/fakeLogin.xhtml">
<action execute="#{identity.login}" if="#{not identity.loggedIn}" />
<param name="username" />
<navigation from-action="#{identity.login}">
<rule if="#{identity.loggedIn}">
<redirect view-id="/home.xhtml"/>
</rule>
<rule if="#{not identity.loggedIn}">
<redirect view-id="/error.xhtml"/>
</rule>
</navigation>
</page>
And:
#In(required = true)
private String username;
#In
Identity identity;
public boolean authenticate() {
//...
throw new AuthorizationException("login failed");
//...
return true;
}
Related
I'm using Spring Security to Secure my Web App.
I have a page where I show foo objects for administrators.
<intercept-url pattern="/show_foo/**" access="hasRole('ROLE_ADMIN')" />
But now I have a requirement that a foo cannot be seen by all the Administrators, for example only administrators with city="New York" can access to the element.
I've did something in my controller to solve this :
#RequestMapping(method=RequestMethod.GET,value="/show_foo"
public ModelAndView showfunction(Principal user)
{
User user2 = userService.getUserByName(user.getName());
if(/* some checks on user2 */)
/* show page */
else
/* show error page*/
}
So my question is : can I avoid the database call, because I need this almost in all of my pages and I find it ugly to check each time at the top of any controller the same thing over and over. Is there a Spring Security feature for this kind of use cases?.
With Expression based rules you can accesss principal even on rule. See: http://docs.spring.io/spring-security/site/docs/3.0.x/reference/el-access.html
For example if you can include needed information on principal object.
<intercept-url pattern="/show_foo/**" access="hasRole('ROLE_ADMIN') and principal.name=='xyzzy' " />
you have to put in some logic.
1.) Either load the user and country mapping and store somewhere in Static HashMap, remember to update the map if any changes done in mapping, can store same at session level.
2.) Load entries in 2nd level cache, or make queries cacheable, enable query caching as well.
You need to integrate Spring Security with Domain-ACLs. See a full explanation here.
Yo can consider mapping the relationship between Administrators and Cities using
ACL_OBJECT_IDENTITY instances.
I working on Spring MVC app. The app funcionality is accessible through ReST API which jsp containing ajax logic consume. I am using spring security with defined roles (USER, COMPANY, ADMIN). Methods use requestMapping with responseBody such as:
www.app.com/auth/{userId}/request/{requestId}
It, of course, support GET for obtaining resource and POST for its creating or updating.
The problem is that after succesful login with, for example, userId = 1 I want GET request with requestId = 99. But when I run WebDev client for Chrome, I can also access another resource with easy request in format
www.app.com/auth/5/request/{requestId}
So basically, I can access resources, which I am not allowed to see. I hope you got the idea, where I am heading.
My question is - What is the best approach to secure this?
I was thinking about storing logged user Id (Integer) in session and comparing it everytime request for resource is made, but it seems to me that I am pulling the wrong end of rope :)
Thank you for any advice
You should have a look into the Expression-Based Access Control section of the spring security documentation.
Example copied from the documentation:
#PreAuthorize("#contact.name == authentication.name")
public void doSomething(Contact contact) {
..
}
This would check if name of the contact is equal to the name of the currently logged in user.
Using this this feature you can build much more sophisticated access rules than you could do with simple roles. However, this does not exclude using roles. You can still keep roles for basic security checks.
I want to see if it is possible to use annotations to evaulate if a user is logged in or not.
Example
#AuthRequired
public String myProtectedArea() {
return View("view/protectedArea"); // If user is NOT authenticated, return "view/login"
}
As per your edit:
Check this SO Post:
Scanning Java annotations at runtime
I'd still recommend using Spring Security for this, it's tested and secure:
#PreAuthorize("hasRole('ROLE_USER')")
public String myProtectedArea() {
return View("view/protectedArea");
}
The annotation will check if the user is logged in and has the required credentials.
Another way with Spring Security is to intercept the URL pattern by setting this inside a spring.security-settings.xml:
<intercept-url pattern="/view/protectedArea/*" access="hasRole('ROLE_USER')" />
I'd recommend using both to maximize security.
In the security settings file you can then tell spring security where to redirect the user to login. If the user is already logged in, you can redirect him to yet another page:
<form-login login-page="/view/login.xhtml" default-target-url="/view/protectedArea/home.xhtml"
authentication-failure-url="/view/login.xhtml" />
It's a tested framework and thus secure and versatile. However it requires a bit of setting up if you want more than the standard behaviour.
The annotation doesn't check if the user is logged in or not--annotations are metadata on classes/methods. Something must still make use of the annotation.
Something in your code checks to see if the method is annotated with #AuthRequired, if it is, checks if logged in, then executes the method based on that.
For example, a web app might look for the annotation in a filter, base servlet, interceptor, etc. and decide whether or not the request process should continue.
Depending upon what type of application you are creating there are a number of options available to you for defining authentication levels for specific methods.
I would most likely recommend to you Spring Security for such a task.
Something like the below example would be the end result after configuration using Spring Security.
#Secured( {"USER_ROLE"} )
public String getSecretData() {
return "SECRET! SHHH!";
}
Then only users verified by Spring Security to have the role you provide to the annotation will have authorization to call the method.
There are a couple other annotation options in Spring Security you can utilize such as #PreAuthorize.
Instead of re-inventing the wheel, have a look at JAAS:
http://docs.oracle.com/javaee/6/tutorial/doc/bncbx.html#bncca
http://docs.oracle.com/javaee/6/tutorial/doc/bncas.html
http://docs.oracle.com/javaee/6/tutorial/doc/gijrp.html
http://docs.oracle.com/javaee/6/api/javax/annotation/security/package-summary.html
I'm new to Acegi. I have it working in its simplest form. I have to login in order to access the protected pages (I followed their tutorial).
Now I want to have a DB Log of every successful login. Is there a simple way to do that? Something like forcing a specific action (which I would create and would write the information to the DB) every time there's a succesful login, or maybe some internal ACEGI feature that does it for me?
Currently I'm thinking of setting defaultTargetUrl to a redirect page which would store the current user to the DB and then redirect to index. But I'm not sure this would work if someone accessed the login via trying to access other page that isn't index (as after logging in, acegi seems to redirect the user to that page, which is the behaviour I want anyway)
Any ideas about this? I'd really appreciate them.
Thanks.
B.
You may use Spring's event handling mechanism to get notified on AuthenticationSuccessEvent published by Spring Security.
I would do it via AOP, if possible.
This solution applies for Spring 3.x and Spring Security 3.x. Spring Security is the direct successor of Acegi, I'd use that instead if possible. I hope this applies to the former version.
#AfterReturning("execution(* org.springframework.security.web.authentication.SimpleUrlAuthenticationSuccessHandler.onAuthenticationSuccess(javax.servlet.http.HttpServletRequest, javax.servlet.http.HttpServletResponse, org.springframework.security.core.Authentication)) && args(request, response, authentication)")
public void onAuthenticationSuccess(HttpServletRequest request,
HttpServletResponse response,
Authentication authentication) {
logger.debug(authentication.getPrincipal() + " logged in.");
}
If you don't feel comfortable working with AOP, you can of course build a wrapper on the SimpleUrlAuthenticationSuccessHandler manually.
Can the JSP servlet that filters on *.jsp (org.apache.jasper.servlet.JspServlet in Tomcat 6) be extended in some way so whenever someone goes to a JSP page I can do some server side authentication to check whether the user can view the page. Our current technique is a taglib in a common include that is imported into each JSP page, but it's not very elegant.
The key here is that I don't want to reinvent the wheel and worry about compiling JSPs into Servlets, I would ideally like to delegate in each method with super.meth().
I've been searching Google but I don't know the right keywords to use. Anything containing JSP and Servlet returns beginner tutorials.
Thanks,
John
Look at Servlet Filters, and use that Filter before forwarding to some JSP or Servlet.
When not taking benefit of the Java EE provided container managed security, then the normal basic practice is that you store the logged-in User in the session scope and uses a Filter on the desired url-pattern to check if the User is logged in.
Here's a basic example to get the picture:
Login:
User user = userDAO.find(username, password);
if (user != null) {
session.setAttribute("user", user);
} else {
// Do your thing to show "Unknown login" error.
}
Filter (which is mapped on an url-pattern of for example /secured/*, /protected/*, etc where in you place the restricted JSP pages expect of the login page):
User user = session.getAttribute("user");
if (user != null) {
chain.doFilter(request, response); // Logged in, so continue with request.
} else {
response.sendRedirect("login"); // Not logged in, redirect to login page.
}
Logout:
session.removeAttribute("user");
// Or, a bit too drastically:
session.invalidate();
You can of course also take benefit of what Java EE out of the box provides with regard to security. A commonly used way is the declarative container managed security wherein you can specify users and roles. You just need to declare a <security-constraint> and a <login-config> in the web.xml and configure an user realm in the appserver. The details depends on the appserver used, but if it is for example Tomcat 6.0, then you can find here some documentation about that.
If basic auth isn't sufficient, maybe Spring Security would be better. It's a natural, especially if you're already using Spring. One big advantage is that it's declarative, so you can easily protect URLs just by adding them to security configuration.
Doing this via inheritance would be brittle and require code changes every time you modified your security. Best to have security as a cross-cutting concern.
Can you not create another filter and put it above JspServlet?
This filter would check your security stuff and do some handling (e.g. redirect to login page) if something is wrong.