I am trying to build an “impersonate” page in order to “log in” as another user . I am thus trying to assign the CurrenUser with a vCurrent_XXXX value but the result is that the CurrentUser is set to null ? How do I control this?
MDriven Turnkey checks for the model pattern above and sets the CurrentUser-transient-link on MVC gets based on the IdentityProvider mechanism from the web app.
The MDriven Turnkey app then use the value of this transient link to decide what SysUser to handle as logged in.
Consider changing the CurrentUser transient link to a a ReverseDerived (and derived) link.
Then Turnkey logic can set it - and you can override it.
Add a transient link called ImpersonatedUser - let the derivation of CurrentUser return self.ImpersonatedUser - that would give the effect you want.
Related
In the new SPA (react and angular) web templates for .Net core 5. I'd like to fetch the current logged in User. However, when I try to get a user in the controller the User doesn't have anything populated.
Does anyone know how to achieve this with the new Identity Classes?
I've made a repo of the vanilla reactJS template, the only thing I changed is the line highlighted in my screenshot below to show there's no user set.
I've done a bit of googling and these pages are all I could find on the topic, unfortunately, they don't give enough detail for me to be able to implement anything practical.
https://learn.microsoft.com/en-us/aspnet/core/security/authentication/identity-api-authorization?view=aspnetcore-5.0
https://learn.microsoft.com/en-us/aspnet/core/security/authorization/claims?view=aspnetcore-5.0
Backend:
ClaimsPrincipal currentUser = this.User;
var currentUserName = currentUser.FindFirst(ClaimTypes.NameIdentifier).Value;
ApplicationUser user = await _userManager.FindByNameAsync(currentUserName);
On the frontend if you need yo access it
//with UserManager
UserManager<ApplicationUser> UserManager
#{
var user = await UserManager.GetUserAsync(User);
}
// with SignInManager
SignInManager<ApplicationUser> SignInManager
#if (SignInManager.IsSignedIn(User))
To answer my own question.
In order to populate the User detail in the HttpContext you have 1 of 2 routes. Either change
services.AddDefaultIdentity<IdentityUser>();
to
services.AddIdentity<IdentityUser, IdentityRole>();
or you can continue to use the Core Identity
services.AddIdentityCore<IdentityUser>();
but then you also need to implement your own Microsoft.AspNetCore.Identity.ISecurityStampValidator and add it as transient services.AddTransient<ISecurityStampValidator, MyValidator>();
Your MyValidator implementation will be responsible for validating the cookie. You can see the default implementation here on github
Edit: Under the hood services.AddDefaultIdentity<IdentityUser>(); uses services.AddIdentityCore<IdentityUser>();. I feel like its importatnt to know this.
On creation of new external user from ATG BCC, I need to include some logic like encrypting password and sending email to user. Achieved this functionality by extending GSAPropertyDescriptor class and overriding its getPropertyValue(RepositoryItemImpl pItem, Object pValue) method.
Problem is, this method is getting called only when we click on create button from "General" tab present in users section, but not on click of same create button from other tabs like "Commerce", "Orgs & Roles", "User Segments" and "Advanced".
Please suggest!!
It is not a good idea to override getPropertyValue of an item for this implementation. The right way to do this is to work with the formhandler that is responsible for saving the user. It is a bit tricky to find this formhandler. It will be in the atg/web/viewmapping/ViewMappingRepository/ of the BCC instance. In this repository there will be lots of formhandlers configured for different purposes. You have to pick the one relevant for the user edit. Here is an example of what you might find there:
With this, you go to appropriate Formhanlder, like /atg/web/assetmanager/editor/profile/UserFormHandler mentioned here. And override that component in your module with your own implementation. Once that is done, you'll have the control of the action. You can do your work and pass on the control to super class (the original implementation).
Regards,
Jags
I have a multi-tenant app in which user can select "current company" after they log in.
There is a DB per company but the model is the same, the workflow is the same, and the controller actions are same....The user can switch companies while being logged in and all actions need to be 'directed' to proper DB.
I know it is possible to customize context creation in EFContextProvider<T> by overriding CreateContext() but how do I pass the extra info (parameter, e.g. CompanyId) that would allow me to create context with correct connection string?
Is this possible?
I find the easiest way is to include the tenant id in a custom HTTP header.
Because the tenant id changes during the session, you probably want to create a custom Breeze ajax adapter (wrap the one you're using now) that sets this header dynamically during its implementation of the ajax method.
On the server you fish the header out of the request.
MAKE SURE YOU ARE VALIDATING USER AND HEADER ON THE SERVER
Let's say I have 3 entities: Advert, User and UserRole. And in Web.Api project GetAllAdverts method.
public IEnumerable<Advert> GetAllAdverts()
{
return repository.GetAll<Advert>();
}
When i enter url ../api/advert I get JSON with all Adverts and data about adverts, but I get all data about user and user role too.
How can I get for example all advert data and only UserName form entity User ?
Is this done by creating DTOs ?
Thanks in advance !
Using DTO's is usually a good idea. It is more work, but it gives you full control and it abstracts out peculiarities of a specific data layer.
In your case, if you really only want UserName you even have to use a DTO, because it is impossible to partly load the User as navigation property from Advert.
If it does not matter that you see all properties of User except its navigation properties (like role), you may also consider to (temporarily) turn off lazy loading for the context in the repository and eager load Advert.User by using Include.
I'm wondering if you could suggest me any way to implement "user roles" in GWT applications. I would like to implement a GWT application where users log in and are assigned "roles". Based on their role, they would be able to see and use different application areas.
Here are two possible solution I thought:
1) A possible solution could be to make an RPC call to the server during onModuleLoad. This RPC call would generate the necessary Widgets and/or place them on a panel and then return this panel to the client end.
2) Another possible solution could be to make an RPC call on login retrieving from server users roles and inspecting them to see what the user can do.
What do you think about?
Thank you very much in advance for your help!
Another way is to host your GWT app in a JSP page. Your JSP might contain a snippet of code like this
<script type="text/javascript">
var role = unescape("${role}");
</script>
Where ${role} is expression language expanded from value you computed from the associated servlet / controller and exposed to the JSP.
When your GWT app runs in the browser, the value will be filled out. Your GWT app can easily call out into JS to obtain this value from a native method call, e.g.
public native String getRole() { /*-{ return $wnd.role; }-*/;
So your module could invoke getRole(), test the value and do what it likes to hide / show elements.
Obviously your backend should also enforce the role (e.g. by storing it in the session and testing it where appropriate) since someone could run the page through a JS debugger, setting breakpoint or similar that modifies the value before it is evaluated allowing them to access things they shouldn't be accessing.
Following scenario works for me:
GWT app is behind security constraint.
On module load I make RPC call to retrieve roles from the container. I store them in main GWT module's class as static field, to make it easy for other classes to use it.
Each widget (especially menu) can use roles (e.g. call Main.getRoles()) and construct itself according to roles. I don't pass roles in constructor. Each widget knows how to behave depending on role.
If it's crucial to not only hide things but also enforce them you can use container security and check roles and rights while invoking business methods.
While using GIN you can also create singleton class to store roles retrieved during login and inject it wherever you need it.