How to migrate accounts with passwords hashed using SHA-256 1Iteration in grails 2.5.6 to Grails 4.0.12 - grails

I recently started my attempts at updating this application from Grails 2.5.6 to Grails 4.0.12. I am very new to grails and programming in general so it has been 3 weeks and hundreds of attempts with no success. Everything seems to work fine except the password hashing. Since the passwords were hashed using SHA256 users are unable to login. I've tried various implementations from the internet but sadly none of them worked, so stackoverflow is my last attempt. However, just for context, no errors are thrown in the case anyone wonders; but at the same time if you are asking for any exceptions than you probably don't know how to solve it:(. Well, thanks to anyone that has any tips.
I have tried creating a Sha256 to BCrypt encoder as described by Burt Beckwith here but with no success. That approach doesn't seem tow work for my case.

For those that might encounter this issue, I wrote a very interesting approach.
Grails 4 provides a feature that allows custom encoder (codec) implementation as long as the class is under the utils folder and the class name should end with Codec, i.e. class MyEncoderCodec. read more about this here.
So for those using SHA-256 with 1 iteration, the solution is the following:
Create the encoder
//path grails-app/Utils/OldEncoderCodec.groovy
import java.security.MessageDigest
class OldEncoderCodec {
static encode = { String rawPass ->
MessageDigest md = MessageDigest.getInstance("SHA-256")
md.update(rawPass.getBytes())
byte[] byteData = md.digest()
//convert the byte to hex format - test1
StringBuffer sb = new StringBuffer()
for (int i = 0; i < byteData.length; i++) {
sb.append(Integer.toString((byteData[i] & 0xff) + 0x100, 16).substring(1))
}
return sb.toString()
}
}
Create a controller method to handle the conversion.
import app.Appuser
import grails.converters.JSON
import grails.gorm.transactions.Transactional
import grails.plugin.springsecurity.annotation.Secured
class HelpController {
def springSecurityService
#Transactional
def ajaxEncodeAndUpdatePasswords(){
def username = request.getJSON().u
def rawPass = request.getJSON().p
boolean result = true //I am always returning true, so handle this as you need to; i.e. you could return false if the user was not found and display a message on the form instead of submitting.
def u = Appuser.findByUsername(username)
if(u){
def dbPass = u.password
if(!dbPass.startsWith("{")) {
def encodedPass = rawPass.encodeAsOldEncoder()
if(dbPass == encodedPass){
u.password = rawPass
u.save(flush: true)
}
}
}
render ([result:result] as JSON)
}
}
Use ajax to perform conversion before the form submission; You could use interceptors but I think an ajax call is cleaner and you can avoid overriding and dependency injections. I'm new to programming so I know that this javascript code could be improved. Also note that in my case #login-button is the submit button that submits my form; handling enter key as well.
//path views/login/auth.gsp
$(document).ready(function(){
$('#login-button').on('click', function(event){
event.preventDefault();
nCode()
});
$(window).keydown(function(event){
if(event.keyCode === 13) {
event.preventDefault();
nCode()
}
});
function nCode(){
const u=$('#username').val()
const p=$('#password').val()
$.ajax({
url:'${createLink(controller: 'help', action: 'ajaxEncodeAndUpdatePasswords')}',
contentType:'json',
method:'POST',
data: JSON.stringify({
u:u,
p:p
})
}).done((data)=>{
$('#loginForm').submit()
})
}
I am not using the encoder to authenticate users, only to check for a match, then I am just updating the user's password in the database and letting spring security handle the encoding. Hope someone finds this useful.

Related

MVC model bind from VUE object

I am new to VUE and trying to post a complex object with a list of tokens to an MVC c# route.
The network tab from my post request shows:
tokens[0][field]: 129
tokens[0][id]: 1
tokens[0][name]: MyPriority
tokens[0][operator]:
tokens[1][field]:
tokens[1][id]: 3
tokens[1][name]: -
tokens[1][operator]: -
The MVC controller shows the object, and it shows the number of tokens passed. However, the framework is not binding to the properties being passed in (field, id, name, operator). I am unsure if I need to amend the MVC part to bind, or change the JS object before posting.
the MVC controller is
public ActionResult CreateRule(Rule rule, List<Token> tokens)
the Js Code is:
methods: {
saveRule() {
let tokens = [];
debugger;
for (let i = 0; i < this.tokens.length; i++) {
var t = {};
t.field = this.tokens[i].field;
t.id = this.tokens[i].id;
t.name = this.tokens[i].name;
t.operator = this.tokens[i].operator;
tokens.push(t);
}
let newRule = {
id: this.rule.id,
type: this.rule.type,
name: this.rule.name,
field: this.rule.field,
tokens: tokens
};
this.$emit("save-rule", newRule);
},
It does not feel like a great way to have to copy all the parameters into a new object, so I assume this is not the best way. The vue tutorials had it cloning the data for posting to the server. In any case, it has not made any difference to the MVC reading the post data.
I have seen people try Stringify, but issues around datatypes the { ...rule } seemed to make no difference. I was hoping it was a quick answer as it must be possible, it is far from specialized or unique action!

Google SignIn - "access_token" vs "id_token" vs "code"

In our website we used to use access_token when logging people with Google Sign In. First, we redirect the user to google, user brings the access_token to us, and we validate that token to make sure the user is the actual Google user.
Then, we needed a Google sign-in feature for our Android app, so I wanted the Android developer to bring access_token to us. He replied he couldn't. I searched about that finding almost no documentation about access_token. In documentation, Google says me to use the "id_token".
OK, I wanted the developer to bring me the id_token, and I have successfully verified the token's integrity. Then I wanted to implement the same for websites.
My c# code is:
string googleId = GoogleJsonWebSignature.ValidateAsync(idToken).Result.Subject;
It worked when I ran it locally, but when I tried in production, it gave an error: JWT is not yet valid
Is id_token the correct way to send to the backend and verify? I found another option too: code.
Code is something like A/12112312......
Access_token is something like ya29.somemorestring
My question is, Which one is correct to send to the backend? By the way, I think access_token is sort of deprecated or something like that.
Yes, you should be using the id_token. You get the id_token on the client side using this:
var id_token = googleUser.getAuthResponse().id_token;
and validating it on the server side using (do in a try/catch block to catch any errors):
token = await GoogleJsonWebSignature.ValidateAsync(idToken);
The JWT is not yet valid error is due to the time on your server being slow. Even a few seconds slow will cause this problem. To be sure of this working all the time, you'll need to implement a custom clock which gets an accurate time from somewhere. Here's an example using NNTP:
public class AccurateClock : Google.Apis.Util.IClock
{
const int UpdateIntervalMinutes = 60;
const string NntpServer = "time.nist.gov";
private TimeSpan _timeOffset;
private DateTime _lastChecked;
public AccurateClock()
{
_timeOffset = TimeSpan.FromSeconds(0);
_lastChecked = DateTime.MinValue;
}
private DateTime GetTime()
{
try
{
if (DateTime.Now.Subtract(_lastChecked).TotalMinutes >= UpdateIntervalMinutes)
{
// Update offset
var client = new TcpClient(NntpServer, 13);
DateTime serverTime;
using (var streamReader = new StreamReader(client.GetStream()))
{
var response = streamReader.ReadToEnd();
var utcDateTimeString = response.Substring(7, 17);
serverTime = DateTime.ParseExact(utcDateTimeString, "yy-MM-dd HH:mm:ss", CultureInfo.InvariantCulture, DateTimeStyles.AssumeUniversal);
}
_timeOffset = DateTime.UtcNow.Subtract(serverTime);
_lastChecked = DateTime.Now;
}
var accurateTime = DateTime.UtcNow.Subtract(_timeOffset);
return accurateTime;
}
catch (Exception ex)
{
return DateTime.UtcNow;
}
}
public DateTime Now
{
get
{
return GetTime().ToLocalTime();
}
}
public DateTime UtcNow
{
get
{
return GetTime();
}
}
}
You then pass the custom clock to the validation method.
token = await GoogleJsonWebSignature.ValidateAsync(idToken, new AccurateClock());
Please note: This will update the difference between the correct time and the local machine time every time the class is created, so you really want to register this as a Singleton in whatever IOC container you are using and pass the reference to the validator instead. It will then recheck the time using NNTP every hour. If you are not using an IOC Container you could make the class static.
id_token is a JWT token, that you validate and extract information such as "email", "name" etc. This is actually what you need in a regular case.
code and access_token are part of the flow when a user doesn't use your app in current moment but your app wants to make any actions behalf of them. Google calls it offline access https://developers.google.com/identity/sign-in/web/server-side-flow

Unit test Custom authorize attribute

I've written a custom claims authorizatize attribute and I would like to unit test the code I've written but have been unable to find what I'm looking for on SO.
For example, this is my custom authorize attribute class:
using System.Collections.Generic;
using System.IdentityModel.Tokens.Jwt;
using System.Linq;
using System.Security.Claims;
using System.Web;
using System.Web.Mvc;
using System.Web.Security;
using IPD2.MVC.Interfaces.Providers;
using IPD2.MVC.Providers;
namespace IPD2.MVC.Attribute
{
public class ClaimsAuthorizeAttribute : AuthorizeAttribute
{
private readonly string _claimValue;
private readonly string _claimType;
private readonly ITokenProvider _tokenProvider;
public ClaimsAuthorizeAttribute(string type, string value)
{
_claimType = type;
_claimValue = value;
_tokenProvider = new TokenProvider();
}
public override void OnAuthorization(AuthorizationContext filterContext)
{
var jwt = _tokenProvider.ApiToken as JwtSecurityToken;
if (jwt == null)
{
HandleUnauthorizedRequest(filterContext);
}
else
{
var claim = jwt.Claims.FirstOrDefault(expr => expr.Value == _claimValue);
var authCookie = HttpContext.Current.Request.Cookies[FormsAuthentication.FormsCookieName];
if (authCookie != null)
{
var formsAuthenticationTicket = FormsAuthentication.Decrypt(authCookie.Value);
if (formsAuthenticationTicket != null && !formsAuthenticationTicket.Expired)
{
var roles = formsAuthenticationTicket.UserData.Split(',');
HttpContext.Current.User = new System.Security.Principal.GenericPrincipal(new FormsIdentity(formsAuthenticationTicket), roles);
}
}
if (claim != null)
{
base.OnAuthorization(filterContext);
}
else
{
HandleUnauthorizedRequest(filterContext);
}
}
}
}
}
Test code
public class GivenCallingClaimAuthorizationAttribute : SpecsFor<ClaimsAuthorizeAttribute>
{
//HttpActionContext actionContext;
//IPrincipal originalPrincipal;
protected override void Given()
{
SUT = new ClaimsAuthorizeAttribute(ClaimTypes.Role, "ImNotAllowedToUseController :(");
}
public class WhenUserIsNotAllowedToAccessController : GivenCallingClaimAuthorizationAttribute
{
protected override void When()
{
SUT.OnAuthorization(
new AuthorizationContext()
);
}
}
[Test]
public void ThenAssertSomethingBasedOnCodeInTest()
{
//todo: some assert
}
}
I've written this basic test class with the SpecsFor BDD framework but I'm not sure what it needs to test it succesfully.
Any ideas on how to test this? As you can see, I'm testing the class itself rather than a controller with the attribute. I'm not sure about a good way to test this.
If you want to do BDD, think about the behaviour of your class. What kind of things should it be able to do?
For instance, perhaps it should:
- authorize current users
- filter users whose ticket has expired
- assign authorized users with the correct roles
- etc.
Let's say we're going to look at the second one of those, because it's interesting. I'll ask you, "Can you give me an example of when a ticket might expire?"
And you say, "Yes, the timeout is 500ms so anything older than that is expired." Or you say, "These are tickets to a football match and are given out yearly." (I don't know what a ticket is, but this conversation would help me work that out.)
So then we can write an example:
Given we've got a handler for unauthorized tickets
Given Fred's ticket expired on 2017-05-14
And it's now 2017-05-14
When we try to authenticate Fred
Then Fred should not be authenticated
And the handler should be given Fred's details
Next I like to put these in comments in code, with the "should" as the title of the test. After that, it's just a matter of setting up the context (in the Given), passing it to your code to exercise (the When) and verifying the outcome (the Then).
However, you can see that your Specs framework only allows for one given! That's not great, since I've already identified several scenarios which require different contexts. If you use SpecsFor the way you're using it, you'll have to make one class for each of my scenarios, and they won't be very easy to read!
I highly recommend using the second style instead, and start just with the Given, When, Then in comments.
The thing is, unit tests' steps aren't really reused much, compared to say a full-system BDD scenario, in which contexts are often called several times for different capabilities. A unit of code (or class) tends to fulfil one responsibility, or it gets refactored that way, and its contexts don't bleed into other classes because Mocks.
So, I find that just having Given, When and Then in comments is enough.
I therefore recommend you switch to the "old school" way of doing things that I can see in this page (down the bottom) and just start with the comments. See how that goes for you.
By the way, if you really want to do BDD properly, then you want to drive the development with the examples of how it behaves, and incrementally fill in the code to make those examples work, rather than writing them down. The book "Growing Object Oriented Software, Guided By Tests" will be very helpful for you.

How to check whether username already exists using ajax in asp.net?

I am working on an application which has a registration form and I have to display to the user whether the username exists or not.
I am using asp.net mvc3 and planned to use AJAX to achieve this.
I have a form
<tr>
<td>User Name*</td>
<td><input id="UserName" name="UserName" type="text" onblur="check(this.value);"/></td>
<td id= "UName"></td>
</tr>
which calls a .js file that has the folling contents
function check(User) {
...
var url = "/UserNameCheck/Index";
url += "?User=" + User;
xmlHttp.onreadystatechange = state_Change;
xmlHttp.open("GET", url, true);
xmlHttp.send(null);
}
function state_Change() {
if (xmlhttp.readyState == 4) {// 4 = "Response loaded"
if (xmlhttp.status == 200) {// 200 = Response Error Free
document.getElementById("UName").innerHTML = xmlHttp.responseText
}
else {
alert("Problem retrieving XML data");
}
}
}
I alerted the username and I am getting the correct value that i had entered. Now, the URL is /UserNameCheck/Index where UserNameCheck is a controller and Index is a method in that.
The controller has this code.
public ActionResult Index(string User)
{
string UserName;
try
{
Response.Cache.SetCacheability(HttpCacheability.NoCache);
UserName = Request.QueryString["User"];
ConnectionPackage.ConnectionClass cc = new ConnectionPackage.ConnectionClass();
conn = cc.con;
string sql = "Select UserName FROM UserDetails where UserName = '" + UserName + "'";
conn.Open();
SqlCommand cmd = new SqlCommand(sql, conn);
cmd.CommandType = CommandType.Text;
object p = cmd.ExecuteScalar();
cmd.ExecuteNonQuery();
string u = (string)p;
if (u.Length==0 || u.Equals("NULL") || u.Equals("null")||u.Equals("Null"))
{
return View();
}
return null;
}
catch (Exception ex){
}
and the view has
String buffer = " <table><tr><td id = 'UName' >" This user name already exists. Please select some other unser name.
buffer = buffer + "</td></tr></table>";
response.getWriter().println(buffer);
I also tried writing
Response.Clear();
Response.Write("UserName already exists. Please select another UserName");
Response.End();
instead of returning View.
But in both the cases, I didn't get any message that the username exists even though I typed a user name that was already present in the database.
The connection string work for inserting into the database, so I dont think there is a problem with that. Is there a problem with the URL that I have mentioned in the js file? Or is my entire approach wrong?
I am basically from java background so dont know much about asp.net. Please do help.
Thank you very much in advance.
I followed what was given in MSDN article How to: Implement Remote Validation in ASP.NET MVC
jQuery in Action is the most popular jQuery book
You're doing alright but you could make this a whole lot easier on yourself. If you are usinng MVC3 with Razor, your app already has jQuery installed.
Use the $.ajax() method to perform the calls to your controller action that checks names...
Bind the $.ajax() call "unobtrusively" which means instead of on your HTML control, bind the event to your control from the jquery/javascript.
Second, if you want a little fancy performance, you can bind it via the live() jquery function or keyup event, so that as you are typing the ajax call is made and you find out realtime.
Ultimately you will end up with a lot less javascript, and your JS stuff will be cleanly separated from your markup.
As far as your controller action is going, it looks fine for playing around and learning, but you'd want to think about either (a) putting your SQL statement as a stored procedure on the db server and calling that, or (b) writing a repository pattern class and then using LINQ to do your query work after the DB fetch.
Another possibility would be to use Entity Framework 4.1 via NuGet to eliminate both needs. It can have a bit of a learning curve, but there's lots of good stuff out there and your example would be fairly simple to get started with.
Let me know if you have any specific concerns with your code and I can provide a more detailed answer.

Grails: User evaluator for Commentable with Spring Security plugin

I am trying to use the commentable plugin with Spring Security.
I can't manage to write the right
grails.commentable.poster.evaluator
I tried {User.get(springSecurityService.principal.id)},
but from the CommentController, both User and springSecurity seems unaccessible.
What should I do?
For springSecurityService.principal.id since there's no dependency injection field for springSecurityService it can't work, so you need to call what springSecurityService.principal.id calls - org.springframework.security.core.context.SecurityContextHolder.context.authentication.principal.id
To fix the problem with User, you'll need the full class name with package. So combined, this should be
{com.yourcompany.yourapp.User.get(org.springframework.security.core.context.SecurityContextHolder.context.authentication.principal.id)}
I adapted Burt's answer such that it doesn't throw an exception if nobody is logged in
grails.commentable.poster.evaluator = {
def principal = org.springframework.security.core.context.SecurityContextHolder.context.authentication?.principal
if (principal?.hasProperty('id')) {
def currentUserId = principal.id
if (currentUserId) {
com.yourcompany.yourapp.User.get(currentUserId)
}
}
}

Resources