Member log in via API - silverstripe

I want to log a member into Silverstripe via curl request. For example: site.com/subdomain/login/authenticate?email=address&username=name&etc
Quick and dirty example controller action...
class RemoteLoginController extends Controller {
public function authenticate($request) {
$email = $request->getVar('email');
....
if (($member = DataObject::get_one('Member', "Member.Email = '$email'"...))) {
Debug::show($member);
$member->logIn();
}
}
}
Debug::show($member) is returning my member, but $member->logIn() is not logging the member in. When I navigate to the home page of the site after making the call in my browser, I am not logged in as the member.
How do I log a member into Silverstripe via API?

Related

Symfony Security - Checking User Role in constructor of service

I need to check if a user has admin rights in a service. The function that is being called in this service might be called a whole bunch of times for a single request. One could check for the role of the user once and save the result like this:
class myService
{
private $accessGranted;
public function __construct(Security $security)
{
// user might not be set up yet?
$accessGranted = $security->isGranted('ROLE_ADMIN');
}
public function someFunctionWithSecurity()
{
if( $accessGranted )
// do the admin stuff here
else
// do slightly different stuff here
}
}
This seems to work just fine when I test it locally.
I was wondering if there is anything wrong with this setup, or if this will lead to strange/unwanted results.

Correct way to validate query string parameters to authorize a ASP.NET CORE request

Shopify allows to embed pages into the admin site, to do that I can create a page using ASP.NET MVC and get the page shown in the admin panel of Shopify.
To validate if the page request is valid and was request by Shopify there are some parameters sent in the query string that the page has to validate before processing the request and render the page.
Shopify sends a hmac parameter so I can calculate the same parameter and validate if both are equal.
I was using Asp.Net Mvc 5 and used the AuthorizeAttribute class but now I am using Asp.Net Core and it seems authorization filters have changed.
I have read some articles about how is the new authorization system in Asp.Net Core but I can't determine what is the best way to do it.
So in the end I need:
Crete a custom attribute so I can add it to my controllers. When Shopify calls my pages I need to verify the query string parameters before the controller action starts to process the request, in the case the request is not valid the controller action is not called but if the request is valid it authorizes and lets the controller action to execute and render the page.
My current filter in Asp.Net MVC 5 is something like this:
namespace MyShopifyApp.Filters
{
public class EmbeddedAppAuthAttribute : AuthorizeAttribute
{
protected override bool AuthorizeCore(HttpContextBase httpContext)
{
//Validates if the nonce/state from the query string is correct
var stateParameter = httpContext.Request.QueryString["state"];
var nonce = ShopifyHelper.AuthorizationNonceManager.GetNonce(ProjectSettings.ShopifyShopUrl);
if (!string.IsNullOrEmpty(stateParameter))
{
if (string.IsNullOrEmpty(nonce) || stateParameter != nonce)
{
return false;
}
}
//Validates if the shop parameter from the query string is valid
var shopParameter = httpContext.Request.QueryString["shop"];
if (!ProjectSettings.IsValidShop(shopParameter))
return false;
//Calculates a HMAC signature and validates if the request is really from Shopify
if (!ShopifyAuthorizationService.IsAuthenticRequest(httpContext.Request.QueryString, ProjectSettings.ShopifyAdminAppApiSecret))
return false;
//Everything is correct so allow the request to continue
return true;
}
protected override void HandleUnauthorizedRequest(AuthorizationContext filterContext)
{
}
}
}
This is an example controller:
namespace MyShopifyApp.Controllers
{
[EmbeddedAppAuth]
public class MyController : Controller
{
public async Task<ActionResult> Index(string hmac, string shop, string signature, string timeStamp, string protocol)
{
//Do something here only if the request is authentic and sent by Shopify
}
}
}

MVC 6 Areas and multiple login pages redirect

I'd been searching for a solution to this problem for quite a long time but unfortunately haven't found any nice and elegant way to handle it.
Here are the details:
My MVC 6 application use Areas. Each area has separate directories for the Controllers, Views etc.
Authentication is based on the standard out of the box web application template with user accounts stored in sql server
What I want to achieve is:
When user enters /AreaA/Restricted/Page then he is redirected into /AreaA/Account/Login
When user enters /AreaB/Restricted/Page then he is redirected into /AreaB/Account/Login etc...
Even though I can change the stanard login page redirect from "/Account/Login" into something different like this:
services.Configure<IdentityOptions>(options=> {
options.Cookies.ApplicationCookie.LoginPath =
new Microsoft.AspNet.Http.PathString("/HardcodedAreaName/Account/Login");
});
I am not able to redirect into different actions/login pages for each area.
Prior to MVC 6 I was able to use AuthorizeAttribute with url parameter:
public class CustomAuthorization : AuthorizeAttribute
{
public string Url { get; set; }
// redirect to login page with the original url as parameter.
protected override void HandleUnauthorizedRequest(AuthorizationContext filterContext)
{
filterContext.Result = new RedirectResult(Url + "?returnUrl=" + filterContext.HttpContext.Request.Url.PathAndQuery);
}
}
and then passing the area dependent url by decorating each controller:
[CustomAuthorization(Url = "/Admin/Account/Login"]
public class AdminAreaController : Controller
{ ...
But it does not work anymore :(
Try the following and see if it works (I did try this and it works fine, but not sure If I have covered all scenarios):
The place where you register you CookieAuthentication middleware, you can do something like
app.UseCookieAuthentication(o =>
{
o.LoginPath = "/area1/login1";
o.AuthenticationScheme = "scheme1";
//TODO: set other interesting properties if you want to
});
app.UseCookieAuthentication(o =>
{
o.LoginPath = "/area2/login2";
o.AuthenticationScheme = "scheme2";
//TODO: set other interesting properties if you want to
});
On you controller/action, specify the authentication scheme..example:
[Authorize(ActiveAuthenticationSchemes = "scheme1")]
public IActionResult Test1()
{
return Content("Test1");
}
[Authorize(ActiveAuthenticationSchemes = "scheme2")]
public IActionResult Test2()
{
return Content("Test2");
}

How get user name in MVC WebAPI Controller

I have a Logon Controller Get method where I want to return the user id.
I am using basic authorization and all work fine but in the Get method I am not able to get the correct user id.
This is the code :
public class LogonController : ApiController
{
[BasicAuthorize]
public string Get()
{
int id = WebSecurity.CurrentUserId; // returns -1
return id.ToString();
}
}
My application is based on MVC 4 internet template with authentication mode="Forms"
I am not sure how to configure the two authentication modes even they seem to be working.
Any suggestion ?
Thanks

What is the correct way to implement login with redirect using JSF 2.0?

Part of my site should be accessible only to authorized users. Let's assume user would enter page a.html which belongs to the authorized-only part.
If I was to use servlets/JSP I could write a filter that checked whether user is logged in and if not - redirected him to login page. After a successful login user would be redirected to the page he wanted to reach initially, in this case a.html. (Page address could be stored in request).
What is a proper way to implement such scenario in JSF 2.0?
Just do it the same way, with a Filter. It's good to know that JSF session scoped managed beans are under the covers stored as a HttpSession attribute with the managed bean name as key.
Assuming that you've a managed bean like this:
#ManagedBean
#SessionScoped
public class UserManager {
private User user;
// ...
public boolean isLoggedIn() {
return (user != null);
}
}
Then you can check it in Filter#doFilter() as follows:
UserManager userManager = (UserManager) ((HttpServletRequest) request).getSession().getAttribute("userManager");
if (userManager != null && userManager.isLoggedIn()) {
chain.doFilter(request, response);
} else {
((HttpServletResponse) response).sendRedirect("login.xhtml");
}

Resources