I have the mechanism to save cookies at the client-side. But when I was trying to implement remember-me using spring security I came upon this tutorial :
http://static.springsource.org/spring-security/site/docs/3.0.x/reference/remember-me.html#remember-me-persistent-token
but here everything is abstract and no examples are given..
Can someone tell me how can I use the interfaces mentioned in this tutorial in my application where I need to implement persistent cookies... And kindly tell me what do I need to define in my security.xml file?
I am authenticating my user against RESTful services..
The official documentation is not abstract. Turning on remember-me with Spring Security is very simple (I suppose that Spring Security already configured and users are stored in DB):
1 Turn on remeber-me in the conf :
<http>
...
<remember-me data-source-ref="yourDataSource"/>
</http>
2 Create corresponding table in the database:
create table persistent_logins (username varchar(64) not null, series varchar(64) primary key, token varchar(64) not null, last_used timestamp not null)
3 Add corresponding checkbox to your login form:
<input id="rememeberMe" type="checkbox" name="_spring_security_remember_me">
In a case of REST you need to adjust third step according to your authentication scenrio.
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.
Here is what I'm trying to do: I have an authentication EJB that can grant user a "ticket" (pair of key and token) by validating username and password. Clients should pass the ticket every call to remote EJB and such ticket should be able to be fetched by EJB (method, or interceptor) and EJB/ or interceptor should validate the ticket and determine whether the call is valid or not.
I don't want to add ticket as parameter to each function that requires authentication, and I believe there should be a way to implement this. I've looked through several articles about JAAS custom login module, but still can't find a non-vendor specific way to do this. (And I am trying to avoid vendor specific implementation)
If JAAS can't do the job, is there anything like "header" in EJB?
Couldn't you just use roles to perform this authorization? Instead of granting a ticket to a user, assign him a role.
Then, it's just a matter of using the inbuilt functionality of checking whether a user is in a role or not.
Although I agree with #EdH, i.e. use #RunAs, you can accomplish what you want by adding to the EJB context your token.
Red Hat does something similar here by using the interface EJBClientInterceptor.
By looking the code of ReceiverInterceptor (which implements the EJBClientInterceptor) you can see how to modify the EJB context (on the client-side) and add your token:
context.setReceiverInvocationContext(new
EJBReceiverInvocationContext(context, receiverContext));
context.sendRequest();
What I need:
For each new user visiting my site I create a MyUser object (doesn't matter what this class consists of) and persist it to DB.
And I want this object to be used each time user with same sessionId come on my site.
For me it looks almost like anonymousAuthentication. So I disabled it and replaced with my own filter:
<http auto-config="true">
...
<anonymous enabled="false"/>
<custom-filter ref="userGeneratorFilter" position="ANONYMOUS_FILTER"/>
</http>
I thought that securityContext contains principal for previously authenticated user but it looks like one of the filters in filterchain adds it manually for each request.
In other words each time I get into my UserGeneratorFilter.doFilter
SecurityContextHolder.getContext().getAuthentication() == null;
So how can I understand whether I need to create a new MyUser object or take an existing one from data base?
ps. I think I've choosen kind of a wrong way=( Few words about my task: I want unauthorized user to have limited access to my resource but when he registers I want all the data he entered while being unauthorized to be merged into his normal account.
Thank you for your attention. Each time I write that sentence moderators remove it. But I will never stop writing it=)
Just set a cookie which does not expire with something like a CookieID or a VisitorID that identifies the user. check for this cookie when people visit your site, it should identify the user.
There are options in spring security that tells how security should handle session migration, maybe that would be helpful for you.
I'd like to know how to combine these two authentication steps :
check the user/password in an LDAP
add principals (roles) found in a DB to the subject.
The LDAP user repository have no idea about application-specific roles and I don't want to manage the passwords in the application DB. So I need both.
JAAS configuration file allows to have additional LoginModules :
<name used by application to refer to this entry> {
<LoginModule> <flag> <LoginModule options>;
<optional additional LoginModules, flags and options>;
};
but I can't find example that explains how I works.
Is it the good method ?
Thanks
=========================================
Here is my answer :
Indeed we can have additional LoginModules. The JAAS configuration file is :
Sample {
com.sun.security.auth.module.LdapLoginModule Requisite
userProvider="ldap://acme.org:389/OU=Users,OU=_ACME,DC=acmegis,DC=acme,DC=org"
authIdentity="{USERNAME}"
userFilter="(userPrincipalName={USERNAME})"
storePass=true
sample.module.SampleLoginModule required debug=true;
};
Here we have two LoginModules :
The Sun's LdapLoginModule that checks user/password,
and mine sample.module.SampleLoginModule that query my db and fills the principals.
The important parameter is storePass=true that asks the LdapLoginModule to store the username and password in the module's shared state. (see http://docs.oracle.com/javase/6/docs/jre/api/security/jaas/spec/com/sun/security/auth/module/LdapLoginModule.html).
So the next LoginModules can get the username passed to the initialize method in the sharedState Map argument. They should have nothing to do in login() and the query in DB to fill the Principales is done in commit() (like Shimi Bandiel said).
I don't use it yet but there is a DatabaseServerLoginModule developed by JBoss (see http://community.jboss.org/wiki/DatabaseServerLoginModule) that supports authentication and role mapping. Used with password-stacking=useFirstPass we should have the answer to my need without write any line-code (but a beautiful JAAS configuration file).
B.R.
You should implement a LoginModule which in the login method you access the LDAP and check username/password and in the commit method you access the DB and fill the principals.
There is no need here to use multiple LoginModule
It is great!
But implement the LoginModule give you more power to customize the way you interact with LDAP server.
I also struggle the same problem as you.
But remember when implement the LoginModule, you should add the role in login() function , not in commit(), otherwise your subjet will not get the principal.
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;
}