User authenticate play framework - authentication

Like many others in here I'm following the documentation about authentication on the documentation in here:
https://www.playframework.com/documentation/2.2.1/JavaGuide4
Everything was ok until I got to the part of implementing the validate function.
public String validate() {
user=User.authenticate(email, password);
if (user == null) {
return "Invalid user or password";
}
return null;
}
Am I suppose to implement the User class? import some library that I'm not aware of?
I'm new at play so please forgive my ignorance!,
and many thanks in advance!

Related

Implementing user session in Sencha and SpringBoot

I am trying to make a web app in Sencha Touch with Springboot as my back-end. My app is going to have users and each one of them is going to have their own separate activity. How do I make my app "know" what user is logged in so it can display their specific details? I am a newbie and don't know exactly how this needs to be done, especially on the server side (Springboot). If somebody could throw some light, that would be awesome! Thanks!
Assuming you are planning to use Spring Security, the current-user data can be obtained through its principal. There are a few ways to get the principal. One way is to have a principal parameter in the controller method, and Spring will inject it. Like this:
#RequestMapping(value = "/user", method = RequestMethod.GET)
#ResponseBody
public String currentUserName(Principal principal) {
return principal;
}
Another way would be to have a utility method like this:
public static User getUser() {
Authentication auth = SecurityContextHolder.getContext().getAuthentication();
if (auth != null) {
Object principal = auth.getPrincipal();
if (principal instanceof User) {
return (U) principal;
}
}
return null;
}
This can then be called from the controller method.

Where to verify authorization for a Command?

The question's title resumes pretty much: where do I verify authorization for a Command?
For example, setting a customer as preferred involves:
MarkAsPreferred controller action (could be Winforms or whatever);
SetCustomerAsPreferredCommand;
SetCustomerAsPreferredCommandHandler;
Customer.MarkAsPreferred() (domain);
I identified 3 places to check for authorization:
UI for displaying purposes (user should not see a link/button if he/she does not have access to it);
controller action to verify the user is authorized to call that command; commands are assumed to always succeed (regarding validation, but I'm assuming authorization too) and we have a chance to inform the user about lack of access;
inside the command just before calling domain logic;
SomeView.cshtml
if (authorizationService.Authorize("MarkCustomerAsPreferred))
{
// show link
}
CustomerController
[HttpPost]
public ActionResult MarkAsPreferred(Guid id)
{
if (!authorizationService.Authorize("MarkCustomerAsPreferred))
{
return RedirectToAction("Unauthorized");
}
var MarkCustomerAsPreferredCommand { Id = id };
...
}
MarkCustomerAsPreferredCommandHandler
public void Handle(MarkCustomerAsPreferredCommand command)
{
if (!authorizationService.Authorize("MarkCustomerAsPreferred"))
{
throw new Exception("...");
}
customer.MarkAsPreferred();
}
My question is: Do I need to verify authorization in 3 places or I'm just being overzealous?
I searched all over the internet but couldn't find any example or reference about this.
Edit
After more research and some tests I think wrapping the commands to add behavior (authorization, validation, logging) as Dennis Taub suggested is easier and cleaner to implement.
I found this blog post which explains exactly this concept.
About having multiple handlers for one command, I don't need to implement one command handler for each behavior for each original command, one wrapping command can wrap all handlers.
I think final authorization should be done on the application service level, i.e. as part of handling the command. You could wrap the command handler with an authorization handler for example.
class AuthorizationHandler : IHandle<SetCustomerAsPreferred> {
IHandle<SetCustomerAsPreferred> innerHandler;
public AuthorizationHandler(IHandle<SetCustomerAsPreferred> handler)
{
innerHandler = handler;
}
public void Handle(SetCustomerAsPreferred command)
{
if (/* not authorized */)
throw ...
innerHandler.Handle(command);
}
}
class SetCustomerAsPreferredCommandHandler : IHandle<SetCustomerAsPreferred> {
public void Handle(SetCustomerAsPreferred command)
{
// do the work
}
}
It's good UI to have that verification in the View, so the user won't click it by mistake. I consider the controller verification the 'real' one, because there is where the command is created. If an user doesn;t have the rights, she shouldn't be able to create (or even reach that action) the command.
I think that putting the check in the handler is a bit overzelous, as it's not its responsibility to do authorization and is not like that handler can be reached by an user directly.

UserNamePasswordValidator and Session Management

I'm using WCF custom Validator with HTTPS (.NET 4.5). Validate on success returns Customer object which I would like to use later. Currently I'm able to do it with Static variables which I like to avoid if possible. I tried to use HttpContext which becomes null in main thread. My understanding Validate runs under different thread. Is there any way I could share session info without involving DB or File share. See related threads here and here.
In Authentication.cs
public class CustomValidator : UserNamePasswordValidator
{
public override void Validate(string userName, string password)
{
//If User Valid then set Customer object
}
}
In Service.cs
public class Service
{
public string SaveData(string XML)
{
//Need Customer object here. Without it cannot save XML.
//HttpContext null here.
}
}
I can suggest you an alternative approach. Assuming that the WCF service is running in ASP.Net compatibility mode and you are saving the customer object to session storage. Create a class such as AppContext
The code would look something like this
public class AppContext {
public Customer CurrentCustomer {
get {
Customer cachedCustomerDetails = HttpContext.Current.Session[CUSTOMERSESSIONKEY] as Customer;
if (cachedCustomerDetails != null)
{
return cachedCustomerDetails;
}
else
{
lock (lockObject)
{
if (HttpContext.Current.Session[CUSTOMERSESSIONKEY] != null) //Thread double entry safeguard
{
return HttpContext.Current.Session[CUSTOMERSESSIONKEY] as Customer;
}
Customer CustomerDetails = ;//Load customer details based on Logged in user using HttpContext.Current.User.Identity.Name
if (CustomerDetails != null)
{
HttpContext.Current.Session[CUSTOMERSESSIONKEY] = CustomerDetails;
}
return CustomerDetails;
}
}
}
}
The basic idea here is to do lazy loading of data, when both WCF and ASP.Net pipelines have executed and HTTPContext is available.
Hope it helps.
Alright this should have been easier. Since the way UserNamePasswordValidator works, I needed to use custom Authorization to pass UserName/Password to the main thread and get customer info again from the database. This is an additional DB call but acceptable workaround for now. Please download code from Rory Primrose's genius blog entry.

How to set Yii::app()->user->name

I tried
public function getName()
{
return 'TEST';
}
in UserIdentity.php but it doesn't seem to change the value of Yii::app()->user->name
In the class UserIdentity that you defined you'll need to set a new state by using setState(name, value) method.
For example in the method authenticate if the user is good:
//if the user is good (good login and good password)
$this->_id=$record->id;
$this->setState('name', $record->name);
$this->errorCode=self::ERROR_NONE;
Then you will be able to call Yii::app()->user->name
A complete example in the Yii guide
The setState() documentation

Log in function in monorail c#

Could anyone give me any good link to log in function in monorail c#?
I am a newbie to monorail c# and need to implement one log in function.
Thank you.
Mealea
Here's one from Ayende Rahien
Like in Ayende's solution, the best way is to just use the ASP.net authentication mechanisms. Here's an example action on a LoginController:
[AccessibleThrough(Verb.Post)]
public void Authenticate(string username, string password, bool autoLogin, string returlUrl)
{
SomeWebServiceAuthenticationProvider wsSecurity = new SomeWebServiceAuthenticationProvider();
bool isValid = wsSecurity.ValidateUser(username, password);
if (isValid)
{
//first perform a logout to make sure all other cookies are cleared
InternalLogout();
FormsAuthentication.SetAuthCookie(username, autoLogin);
PropertyBag["username"] = username;
PropertyBag["password"] = password;
PropertyBag["autoLogin"] = autoLogin;
//redirect back to the Home page, or some other page
if (!RedirectToPreviousUrl()) Redirect("home", "index");
}
else
{
Flash["auth_error"] = "Invalid user name or password.";
RedirectToAction("Index");
}
}
You can substitute some other authentication mechanism in place of 'SomeWebServiceAuthenticationProvider"... the point here is that we're just calling the standard FormsAuthentication methods.