Grails Spring Security Switch User setup problems - grails

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

Related

thymeleaf authorization check always returns true

I'm facing a strange problem with my reactive spring boot project. Here is a piece of code that I've written:
<a sec:authorize="isAuthenticated()" href="/user/account">Account settings</a>
<a th:if="${#authorization.expression('isAuthenticated()')}" href="/user/login">Login or Register</a>
The first link is only visible when user is logged in but the second link is always visible. My plan is to use th:unless for the second one but unable to do so. Does anyone have any idea on this?

How can I setup a link without exposing the link itself?

Actually its not actually a problem, but I'm thinking and searching for it for a while.
When we use php and to setup some link we can use something like-
some link
in this way anyone can see what is going on by looking at the url. Is there any possible way to keep it hidden like the POST method of the form element?
I don't want user to modify and play around with my parameters and values. Lets guess I don't want to encrypt the values and parameters and I can't use form element as they should be pure links. And also what if I don't want to use url rewriting engine.
Any ideas from the experts?
edit:
I forgot to mention another most important thing that I need to get the parameters and the values I want to pass through that link and do some stuffs in the page i'm linking to.
thanks again.
You can use a hidden form
<form action="realurl" method="post">
<input type="hidden" name="parameter" value="value1"></input>
</form>
<a onclick="forms[0].submit();" href="http://fake">link text</a>

How do I add Honey pot fields to my forms?

I've been reading about adding Honey pot fields to my forms for combating bots/spam. Only problem is theirs no guides or anything on where to start. Many sites say to make a field that is hidden that only the spam bot would fill out. But as I'm new to this, don't know where I would start in my application. Could anyone give me the advice on how to set this up? I am trying to make my Devise registration page use honey pot fields.
The basic idea behind honeypot captchas is that you have a hidden (via CSS) field named something like "form" or "email" or "content" that (to a bot just reading the field name) looks like it should be filled in. Then, when the server looks at the submission, you make sure these hidden fields are blank. If they aren't, then you flag the post as a bot.
Here's a well explained example (with some code in ASP), and here's a Rails Gem that provides honeypot captchas.
That Rails Gem I linked looks like it's very easy to use once installed:
<% form_tag comments_path, :honeypot => true do -%>
...
<% end -%>
Although if you're interested in learning about the approach rather than just having it implemented, I'd recommend you roll your own. If you're rolling your own, it's important to make sure that the field is hidden by CSS (or some other style/positioning trick) and not input type="hidden" - as otherwise the bot might not fill out the field.
As Michael Mior pointed out in the comments, it's important to have a message next to the hidden field telling the user to leave it blank - otherwise users with screen readers might erroneously fill it in. This feature is missing from the gem I linked to - so if you're making an accessible website (which you almost certainly should be) you may need to modify it or roll your own.
Keep in mind that this trick isn't foolproof - there's nothing stopping a bot from rendering the page and determining which fields are actually visible to the user before filling any in - but that kind of bot would be considerably more complex than one that just looked at the form html. A honeypot captcha is likely to be very effective at stopping simple bots.
Try invisible_captcha (supports Rails 3, 4 and 5).
It works pretty well for small and medium (in terms of traffic) sites, with a simple and flexible approach. It also provides time-sensitive submissions.
Basic usage
In your form:
<%= form_for(#topic) %>
<%= invisible_captcha %>
...
<% end %>
In your controller:
class TopicsController < ApplicationController
invisible_captcha only: [:create, :update]
...
end
HTML -
<input type="text" name="verifyEmail" id="verifyEmail">
PHP Validation -
if(strlen($_POST['verifyEmail']) > 0){
header('location: {some redirect URL here..}'); //Send them way away from your form :)
die(); //Stop execution of the script
}
CSS -
#verifyEmail{
position:fixed;
visibility: hidden;
top:-500px; left:-500px;
}
dislplay: none; does not show to a bot in HTML (try it with view source)
visibility: hidden; left:-500px; top:-500px; (displays when you view source)
I used display:none honey pots for a while, then switched to visibility option when it occurred to me that the field didn't show in the source code. Do it with a class or id in CSS, not inline style. Notify users with label is good idea, and name is not so important because most bots generally fill in all fields.
Definitely not a catch all but very effective if used with a basic math captcha.
I will share what works 100% for my site right now.
For almost a week we have been testing ways to prevent the high number of fake users called "Spam Bots" as well as "Brute Force Registrations" both are FAKE USERS.
You can find on the internet many ways to apply what is called a honeypot or a hidden field in the registration form.
The purpose of this trick is we fool the FAKE REGISTRATION as it will always fill data in the hidden field thus causing the registration process to DIE preventing the fake registrations.
Now we mentioned many variations of this trick can be found on the internet, and we will explain why our code is quoted as 100% working as for 2 days now it stopped all SPAM BOTS, and all Brute force registrations.
The secret is how we hide the field with a name like "field1" as bots will catch on if we use a common name like password or zip code etc. Using a name like field1 and autocomplete = off force the BOTS to fill in the field and prevents it from determining what the field is for, so it will keep filling it in with data killing the registration attempt.
This image below shows the code we used in the registration form.
<input type="text" name="field1" style="display:none !important" tabindex="-1" autocomplete="off">
This image below shows the code we placed in the PHP form that processes the command to kill the registration if data is entered into the field
if(!empty($_POST['field1'])) die();
For the past 48 hours this code has yielded ZERO SPAM BOTS and ZERO Brute Force Registrations. Enjoy from all of us at AFFA Social
If you wish to manually test this code simply remove the style="display:none from the registration form code above. Try to register putting data in the hidden field, and then registration dies, and if you remove the data from the field the registration will continue.
<div id="honeypotdiv">
If you see this, leave it blank. Only bots should see this
<input type="text" name="body" value="" />
</div>

Users requesting GET when my form method is POST

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.

grails <g:link tag sometimes works and sometimes doesn't>

The
<g:link controller="foo" action="bar">foobar</g:link>
tag sometimes works, that is is renders as
foobar
and sometimes it doesn't. In this case I'll get a
foobar
Does anyone know what conditions cause this tag to fail to expand? Also is there any way to debug the tag expansion logic?
To debug - the file you need is at
$GRAILS_HOME\src\java\org\codehaus\groovy\grails\plugins\web\taglib\ApplicationTagLib.groovy
This might not solve your problem or everyone else's, but I had this same problem occur for me. I had a /mywebapp/session/login URL that I wanted to link to, but <g:link controller="session" action="login"> just resolved to /mywebapp/.
But it turns out that I had mapped my context root "/" to show the login page. I had thought it would redirect, but really it exposed the Session.login page at "/". So, when grails was told to create a link to go to Session.login, the simplest link it could come up with that would take me there was "/". So "/" was correct after all.
If you still can't get it working, but you still need a way to generate links relative to your context root, you can use <a href="${createLink(uri: '/foo/bar')}">
Only one remark which may be useful:
If you are in a file .gsp into the folder:
view
controller_name
your_view.gsp
This works fine: >> <a href="${createLink(uri: '/foo/bar')}">
If you are in a file .gsp into the src/template (for example to modify the list.gsp, create.gsp, etc.):
You have to add a backslash like this:<a href="\${createLink(uri: '/foo/bar')}">

Resources