Symfony4, log out the user if the IP has changed - symfony

I want to log out the user if the IP has changed.
I managed to make it by creating a field lastLoginIp in the Users table, setting it in the onAuthenticationSuccess, and then checking in the User::isEqualTo() method:
if($user->getLastLoginIp() !== Utils::getIp()) {
return false;
}
The problem is that it broke impersonation, because of course the IP of the admin is different than the IP of the user.
How can this be implemented? (and the user must not get logged out if somebody impersonates him)

Why not skip ip check if is granted ROLE_PREVIOUS_ADMIN?
if ($this->security->isGranted('ROLE_PREVIOUS_ADMIN')) {
return true;
}

Related

Nginx user restriction checked with cookies

I'm working on a little PHP Service on my webserver for my clients. The concept is simple:
I'm making a website for a client of mine locally. I upload it onto my publicly accesible webserver. Now I don't want anybody to have access onto every website. So I made a login form (via password) with php and html. The userdata is saved in a MySQL Database.
So if a user gets the url of me (e.g. client.raphaelbernhart.at) there is a input field with a password to be filled out. Now if the user submits the password the php script checks is there is a user with this password and creates a session and cookie.
As the information (client websites) are most of the time not very sensitive I wanted to proof with the nginx configuration if a cookie is created at the clients computer and if the path (url) contains the username specified inside the cookie. My configuration for something like this would be:
location /client {
# Check if url contains auth cookie value
if ($request_uri != $cookie_auth){
return 401;
}
}
But this isn't working...
It would be greate if anybody could help me with this problem...thanks
Also I want to check if there is a administrator cookie created and then always send status 200.
Something like this:
# Check if url contains auth cookie value
if ($cookie_auth = "administrator"){
return 200;
}
But this isn't working to.
Try
location /client {
set $deny 1;
if ($uri ~ ^/client/$cookie_auth) {
set $deny '';
}
if ($cookie_auth = administrator) {
set $deny '';
}
if ($cookie_auth = '') {
set $deny 1;
}
if ($deny) {
return 401;
}
... # further processing
}

Control the page user is directed to once they sign into their account

I'm currently using Flow Router to manage page loads. On sign-in I would like to check if the users account has been 'activated by admin' and direct them to one of two pages.
Scenario 1 - User account not active, send user to profile.html
Scenario 2 - User account active, send user to blog.html
I can't find any examples only, could someone please tell me how to do it or direct me to an example I could follow. Thanks!
you can use Accounts.validateLoginAttempt hook on server side like this.
Accounts.validateLoginAttempt(function(attempt) {
if( ! attempt.user || ! attempt.user.profile.status.isActive){
return false;
} else {
return true;
}
});
And this is how you can redirect to user if not active on client side.
Meteor.loginWithPassword(user, password, function( err, res ){
if(err){
//redirect to login or other route
} else {
//redirect to dashboard
}
});

Meteor.loginWithPassword: Amend verification

I'm using accounts-password and Meteor.loginWithPassword to authenticate a user. I want to prevent the user from being able to login unless the email address is verified.
Currently I do this using a Meteor.method and a callback. The callback will only trigger the call to Meteor.loginWithPassword() if the relevant user has a verified email address and trigger the current form to display a validation error. if not. However a tech-savvy user can still trigger Meteor.loginWithPassword() directly in the console. Is there a best practice way to prevent this?
You can prevent logins for users with an email address which has not been verified by using accountsServer.validateLoginAttempt(func), for example:
if (Meteor.isServer) {
Accounts.validateLoginAttempt(function(attempt) {
var user = attempt.user;
if (!user.emails[0].verified) throw new Meteor.Error(403, 'E-Mail address not verified.');
return true;
});
}
If you return false or throw an exception, the login will be aborted.

Can IIS require SSL client certificates without mapping them to a windows user?

I want to be able to map SSL client certificates to ASP.NET Identity users. I would like IIS to do as much of the work as possible (negotiating the client certificate and perhaps validating that it is signed by a trusted CA), but I don't want IIS to map the certificate to a Windows user. The client certificate is passed through to ASP.NET, where it is inspected and mapped to an ASP.NET Identity user, which is turned into a ClaimsPrincipal.
So far, the only way I have been able to get IIS to pass the client certificate through to ASP.NET is to enable iisClientCertificateMappingAuthentication and set up a many-to-one mapping to a Windows account (which is then never used for anything else.) Is there any way to get IIS to negotiate and pass the certificate through without this configuration step?
You do not have to use the iisClientCertificateMappingAuthentication. The client certificate is accessible in the HttpContext.
var clientCert = HttpContext.Request.ClientCertificate;
Either you enable RequireClientCertificate on the complete site or use a separate login-with-clientcertificate page.
Below is one way of doing this in ASP.NET MVC. Hopefully you can use parts of it to fit your exact situation.
First make sure you are allowed to set the SslFlags in web.config by turning on feature delegation.
Make site accept (but not require) Client Certificates
Set path to login-with-clientcertificate-page where client certificates will be required. In this case a User controller with a CertificateSignin action.
Create a login controller (pseudo-code)
[OutputCache(NoStore = true, Duration = 0, VaryByParam = "*")]
[AllowAnonymous()]
public ActionResult CertificateSignIn()
{
//Get certificate
var clientCert = HttpContext.Request.ClientCertificate;
//Validate certificate
if (!clientCert.IsPresent || !clientCert.IsValid)
{
ViewBag.LoginFailedMessage = "The client certificate was not present or did not pass validation";
return View("Index");
}
//Call your "custom" ClientCertificate --> User mapping method.
string userId;
bool myCertificateMappingParsingResult = Helper.MyCertificateMapping(clientCert, out userId);
if (!myCertificateMappingParsingResult)
{
ViewBag.LoginFailedMessage = "Your client certificate did not map correctly";
}
else
{
//Use custom Membersip provider. Password is not needed!
if (Membership.ValidateUser(userId, null))
{
//Create authentication ticket
FormsAuthentication.SetAuthCookie(userId, false);
Response.Redirect("~/");
}
else
{
ViewBag.LoginFailedMessage = "Login failed!";
}
}
return View("Index");
}

With Meteor, how to login from remote server?

I'm trying to use 2 servers using DDP.connect.
My subscription works well, but methods called using Meteor.call needs the user to be authenticated.
How can i connect the user to the remote server ?
You can authenticate this way:
var DDPConnection = DDP.connect(<url>);
DDPConnection.call("login", {
"password":"qwerty",
"user" : {
"email":"email#email.com"
}
},
function(err,result) {
//Check result
}
);
Check out my other answer on the different login options depending on the setup you have/want to use.

Resources