I write the below given code in config.groovy
grails.plugins.springsecurity.providerNames = [
'rememberMeAuthenticationProvider'
]
grails.plugin.springsecurity.rememberMe.cookieName='grails_remember_me'
grails.plugin.springsecurity.rememberMe.alwaysRemember=false
grails.plugin.springsecurity.rememberMe.tokenValiditySeconds=31*24*60*60
grails.plugin.springsecurity.rememberMe.parameter='_spring_security_remember_me'
grails.plugin.springsecurity.rememberMe.key='monitoringApp'
grails.plugin.springsecurity.rememberMe.useSecureCookie=false
grails.plugin.springsecurity.rememberMe.persistent=false
grails.plugin.databasemigration.updateOnStart = true
i write the below given code on my gsp page
<div class="col-xs-7">
<div class="checkbox">
<label>
<input type='checkbox' name='_spring_security_remember_me' id='remember_me'
<g:if test='${hasCookie}'>checked='checked'</g:if>/>
<g:message code="springSecurity.login.remember.me.label"/>
</label>
</div>
</div>
My controller all action are fully authenticated using spring security #Secured(['IS_AUTHENTICATED_FULLY']) But i cannot able to use benefit of spring security remember me functionality.Please help me .
I am using grails version 2.3.0 and spring security :"spring-security-core:2.0-RC2"
The reason why your users, which have used the remember me feature of Spring security are still being prompted to login is because is IS_AUTHENTICATED_REMEMBERED not the same as IS_AUTHENTICATED_FULLY.
IS_AUTHENTICATED_REMEMBERED
requires the user to be authenticated through a remember-me cookie or an explicit login.
IS_AUTHENTICATED_FULLY
requires the user to be fully authenticated with an explicit login.
All of this is outlined in the very well written documentation.
Since you want to allow users to access things either by being remembered or logging in you should strongly consider using IS_AUTHENTICATED_REMEMBERED instead of IS_AUTHENTICATED_FULLY since it supports both cases.
Related
I'm trying to configure the SwitchUser feature of the Spring Security plugin and not having success. For the most part, it seems simple and strati-forward but after getting all the code in place and clicking 'switch' button, it just redirects me to default home url without making the switch.
Does anyone have more info than what already exists on the official Spring Security Core plugin site? I've been Goggling and reading everything remotely related to it and not finding any original info -- most everything is a copy of Beckwith and Talbott's original documentation.
The following is the code for my app:
Config.groovy
grails.plugins.springsecurity.useSwitchUserFilter = true
grails.plugins.springsecurity.interceptUrlMap = [
'/j_spring_security_switch_user': ['ROLE_SWITCH_USER', 'isFullyAuthenticated()'],
'/j_spring_security_exit_user': ['permitAll'],
]
I'm not sure if I should use interceptUrlMap or controllerAnnotations (?), or what criteria would determine which one to use.
The .gsp code:
<sec:ifLoggedIn>
Logged in as <sec:username/>
</sec:ifLoggedIn>
<sec:ifSwitched>
<a href='${request.contextPath}/j_spring_security_exit_user'>
Resume as <sec:switchedUserOriginalUsername/>
</a>
</sec:ifSwitched>
<sec:ifNotSwitched>
<sec:ifAllGranted roles='ROLE_SWITCH_USER'>
<form action='${request.contextPath}/j_spring_security_switch_user' method='POST'>
Switch to user: <input type='text' name='j_username'/><br/>
<input type='submit' value='Switch'/>
</form>
</sec:ifAllGranted>
</sec:ifNotSwitched>
I'm not aware of any other code or settings involved. Let me know if you need more info.
It turns out, all the code for SwitchUser was implemented correctly. Although SwitchUser still doesnt behave consistently, the problem was not with the code included in the question. We had problems with the implementation of roles in Grails.
I wish I had a better answer. I would still like to know more about SwitchUser -- more than what I've found with the Googles.
It seems like the filter only accept switching between users with the role ROLE_SWITCH_USER
I have index.gsp that presents a page. In that page there is a button to register, and a button to log in. Once you have logged in, if the login is ok, the app drives you again to index.gsp. I need that, if the user is logged in, these buttons disappear, and instead say "Hello, [username]". I've tried with this code, but it doesn't work (it is never logged in):
In the Controller:
def dologin(){
def user=Usuario.findByUsernameAndPassword(params.username,springSecurityService.encodePassword(params.password) )
if(user){
redirect (controller:'usuario', action:'index')
}else{
flash.message=message(code:'default.user.not.found', args:[message(code: 'params.username', default:'Usuario'), params.id])
def userlogged = springSecurityService.getCurrentUser()
render view: 'index', model: [user: user]
}
}
In index.gsp (is not full, only the piece that matters):
<sec:ifNotLoggedIn>
<div id="buttons">
<div id="login">Login
</div>
<div id="register">Registrarse
</div>
</div>
</sec:ifNotLoggedIn>
<sec:ifLoggedIn>
<div id="greet">Hello!</div>
</sec:ifLoggedIn>
Any help would be appreciated.
Thank you.
It looks like you're doing your own authentication, rather than going through the spring security authentication process. The <sec:ifLoggedIn> tag relies on spring security handling the authentication.
The usual way this is handled in a spring security app is by posting the login request to /j_spring_security_check, which, behind the scenes, gets filtered by a UsernamePasswordAuthenticationFilter.
Grails and the spring security plugin make this relatively painless by providing a LoginController and auth.gsp that you can use as a starting point. Run the s2-quickstart script (which also creates User and Role domain objects), or just copy them from the spring-security-core templates directory.
I tried it simply
<sec:ifNotLoggedIn> // DO SOMTHING</sec:ifNotLoggedIn>
<sec:ifLoggedIn> // DO SOMTHING</sec:ifNotLoggedIn>
Finally did it simply
<g:if test="${session.user==null}">
<!-- Display buttons-->
</g:if>
<g:if test=${session.user!=null">
<div id="greet"> Hello, ${session.user.username}!</div>
</g:if>
Easier, i think. But, thank you for your answer, ataylor.
Can the form-login tag make use of URLs to external resources?
I have two Web services running in separate application contexts [Case #1]. They could be on separate machines as well [Case #2].
I want the first service to use Spring Security to enforce authentication for certain methods. I want the second service to be used as the authenticating mechanism. If a request is not authenticated when it attempts to invoke a protected method on the first service, the request should be forwarded to the second service for authentication.
Both services are up and running. I have the first service configured and "working" except for the URL it forwards the request to when the user is not yet authenticated.
If the first Web service is located at http://server1/community, can Spring Security forward a user to a different service running in a separate context?
Ex:
<security:form-login
login-page="/auth/login.jsp" />
where /auth is the context of the second service.
Or, can it forward to a different server altogether?
<security:form-login
login-page="http://server2/auth/login.jsp" />
When I attempted the first configuration above, the URL forwarded to became http://server1/community/auth/login.jsp. I wanted http://server1/auth/login.jsp.
The second configuration yielded http://server1/communityhttp://server2/auth/login.jsp.
Clearly, the URLs are taken to be relative to the current context. Is there a way to change that behavior? Or, is there a better way to do what I am trying to do and I just haven't stumbled on it yet? ^__^
Thank you for your help!
-- JS
PS: I posted this earlier as an "Answer" to a previous post by mistake. Sorry.
Yes there is a way to do what you want. The keyword that you need is login-processing-url on the form-login element.
Example:
<form-login login-page="/auth/login" login-processing-url="/auth/example_security_check"/>
Then in your jsp page you want to set the action to whatever you put there:
<form action="example_security_check" method="post">
<label for="j_username">Login</label>:
<input id="j_username" name="j_username" size="20" maxlength="50" type="text"/>
<br/>
<label for="j_password">Password</label>:
<input id="j_password" name="j_password" size="20" maxlength="50" type="password"/>
<br/>
<input type="submit" value="Login"/>
<br/>
<br/>
<input id="_spring_security_remember_me" name="_spring_security_remember_me" type="checkbox" value="true"/>
<label for="_spring_security_remember_me">Remember Me?</label>
</form>
The documentation for the attribute is here
http://static.springsource.org/spring-security/site/docs/3.0.x/reference/appendix-namespace.html
I guess you can overwrite the class LoginUrlAuthenticationEntryPoint and instead of using the tag, you manually add the required elements to the configuration
See form-login doku for the required elements.
its only the UsernamePasswordAuthenticationFilter and the LoginUrlAuthenticationEntryPoint.
I guess you can use the custom-filter tag to add the filter.
I'm seeing an intermittent problem on our web site. Some users are trying to submit forms via GET when my form method is POST. The errors always come from IE users. I have noticed a few UA strings have a reference to "yie8," which I am assuming is Yahoo's IE8 package. I think the Yahoo! toolbar might have something against me, but I can't replicate the problem on IE7 with the toolbar installed. The problem happens not only on this form, but various others, many of which are submitted via Ajax using the jQuery form plugin load() function with an object parameter passed. This example isn't one of those.
A simple fix would be to just take out all of my AcceptVerb() attributes, but that would be totally lame. Anyone ever come across something like this or have any ideas with dealing with it?
Here's an example exception log entry.
We've got a Web problem! Exception thrown:
http://my.web.site/User.mvc/ResetPassword
Method: GET
User: <not logged in>
UserAgent: IE 7 (Mozilla/4.0 (compatible; MSIE 7.0;Windows NT 5.1;.NET CLR 1.1.4322;.NET CLR 2.0.50727;.NET CLR 3.0.04506.30))
Exception: System.Web.HttpException
Message: A public action method 'ResetPassword' could not be found on controller 'MyApp.Controllers.UserController'.
Here's the HTML as it is rendered to the browser.
<form action="/User.mvc/ResetPassword" class="standard-form small-form" method="post">
<fieldset>
<div class="row">
<label for="usernameTextBox">User Name</label>
<input type="text" name="username" id="usernameTextBox" />
</div>
<div class="row">
<label for="emailTextBox">Email Address</label>
<input type="text" name="email" id="emailTextBox" />
</div>
<div class="row">
<label> </label>
<input type="submit" value="Reset Password" />
</div>
</fieldset>
</form>
And here's the signature of my ResetPassword action.
[AcceptVerbs(HttpVerbs.Post)]
public ActionResult ResetPassword(string username, string email)
(and yes, the email address is required to match the one we have on file)
Possibly an answer raising more questions than actual answers, but in the spirit of trying to help...
On the GET calls, are "username" and "email" querystring parameters actually supplied? (your IIS log file may be recording query strings, so check there). If so, then the answer of Ben S may well apply.
If your web site is internet facing, then these calls may just be spiders not playing nicely.
If your site is internal, I'd suspect a user is playing with "refresh".
Have you tracked the client IP addresses which raise these errors?
I don't think you can do anything about this. Some browser plug-ins/toolbars have a feature which allows changing forms from GET -> POST and vice-versa.
If your users are doing this, there isn't really anything you can do.
When website visitors misbehave like this, you have to ask yourself, "What are the chances this is a legitimate misunderstanding?" In my opinion, using the wrong HTTP method is not something a browser does because it's old or buggy or whatever. It's an invalid request, so send 'em a 405 and be done with it.
(I have heard of some browsers and plugins trying to 'preload' pages that are reachable from the current page, but it's a lame 'feature'. My answer is still to treat it as an invalid request.)
I'd say it isn't really your problem. You design your site to work as intended, you put your GET/POST restrictions on your methods (for security or other reasons).
If the user tries to get around your security with some advanced tools/plugins (such as GET/POST switches) it's not your concern. You might want, however, to add some custom error pages to handle those scenarios and warn the user accordingly.
This handy link shows how to make a form that replaces the built-in spring security login form in 2.5.6. Can anyone illuminate the corresponding question for 3.0.3? Something has changed, the old form does not work.
When I click on submit it comes back to the login page with the error flag, and the username changes from what I type to 'null'.
This suggests that the names of the required form fields have changed from j_username and j_password to something else.
I'm also suspicious of
<input type="text" name="j_username" id="j_username"
<c:if test="${not empty param.login_error}">value='<%=
session.getAttribute(AuthenticationProcessingFilter.SPRING_SECURITY_LAST_USERNAME_KEY) %>'
</c:if> />
since AuthenticationProcessingFilter is deprecated.
And the answer is: POST is required now. I wish it had produced that error message the first time.