I am developing a sharepoint feature that should allow only Farm admin to delete a sitecollection. In SiteDeleting event, i need to chech if the user deleting is farmadmin. How should i do that? I got a property to check if user is webadmin(properties.Web.UserIsWebAdmin) or siteadmin(properties.Web.UserIsSiteAdmin) but how to check if the user is farm admin ?
Any help is much appreciated..
SPFarm farm = SPFarm.Local;
farm.CurrentUserIsAdministrator();
These classes reside in Microsoft.SharePoint.Administration namespace. More on CurrentUserIsAdministrator or SPFarm class on MSDN.
public static bool IsFarmAdmin(string loginName)
{
//For Currently Logged in users
//SPFarm.Local.CurrentUserIsAdministrator();
bool isFarmAdmin = false;
SPSecurity.RunWithElevatedPrivileges(delegate()
{
SPGroup adminGroup = SPAdministrationWebApplication.Local.Sites[0].AllWebs[0].SiteGroups["Farm Administrators"];
foreach (SPUser user in adminGroup.Users)
{
if (user.LoginName == loginName)
{
isFarmAdmin = true;
}
}
});
return isFarmAdmin;
}
Related
In my Vaadin application I have a grid displaying book information. I do need to add a context menu to the grid but it shall be conditional.
For anonymous user (i.e. hasn't logged in yet) there shall be no context menu. For logged in user, menu items shall depend on user privileges. I.e. regular user can only add or edit/delete his personal book review. Admin users shall be able to do more - edit book information, change status, etc.
Shall I set/reset context menu after login occurs? If two users simultaneously using the application, will they get different context menus? When user logged out, shall I set context menu to null?
No code is written yet, therefore I am not providing it here.
You advise will be greatly appreciated.
I found the solution by extending GridContextMenu and adding User property into it;
public class BookContextMenu extends GridContextMenu<Book> {
private User user;
private final PanelsConfig config;
private final GridMenuItem<Book> editBookMenuItem;
private final GridMenuItem<Book> reviewMenuItem;
public BookContextMenu(PanelsConfig panelsConfig) {
super();
this.config = panelsConfig;
this.editBookMenuItem = addItem("Edit book",
event -> event.getItem().ifPresent(book -> {
BookPanel bookPanel = config.getBookPanel();
bookPanel.setBook(book);
bookPanel.open();
}));
this.reviewMenuItem = addItem("Reader's review",
event -> event.getItem().ifPresent(book -> {
ReviewPanel reviewPanel = config.getReviewPanel();
reviewPanel.setUser(user);
reviewPanel.setBook(book);
reviewPanel.open();
}));
if (user == null || !user.isReaderActive()) {
editBookMenuItem.setVisible(false);
reviewMenuItem.setVisible(false);
} else if (!user.isAdmin()) {
editBookMenuItem.setVisible(false);
}
}
public void setUser(User user) {
this.user = user;
if (user == null || !user.isActive()) {
editBookMenuItem.setVisible(false);
reviewMenuItem.setVisible(false);
} else {
this.setEnabled(true);
reviewMenuItem.setVisible(true);
if (user.isAdmin()) {
editBookMenuItem.setVisible(true);
}
}
}
}
My goal is to check if user is member of specific active directory group.
In .net mvc i was using this code inside my service
HttpContext.Current.Request.LogonUserIdentity.Groups
.Any(x => x.Translate(typeof(NTAccount)).Value == "some role"
and it worked well.
In .net core mvc 2.1.2 i pass IHttpContextAccessor into service constructor and try to use following
_httpAccessor.HttpContext.User.Identity.LogonUserIdentity.Groups
but there is an issue, because Identity does not contains LogonUserIdentity. I tried to find any solution but i was not successful, how can i get the list of user groups or check if user is member of specific one ?
Except using built-in function which check the permission by "Roles", if you want to check by specific AD Group, you can also use below codes :
public static class Security
{
public static bool IsInGroup(this ClaimsPrincipal User, string GroupName)
{
var groups = new List<string>();
var wi = (WindowsIdentity)User.Identity;
if (wi.Groups != null)
{
foreach (var group in wi.Groups)
{
try
{
groups.Add(group.Translate(typeof(NTAccount)).ToString());
}
catch (Exception)
{
// ignored
}
}
return groups.Contains(GroupName);
}
return false;
}
}
And using as:
if (User.IsInGroup("GroupName"))
{
}
I'm working on a ASP.Net MVC 5 app and using ASP.Net identity 2, and need to authorize users based on roles and permissions. roles and permissions is not related to each other. for example, to access "action1" action method,( "admin" role ) or ( combination of "role1" and "permission1" ) must exist for him, but other users that is not in "admin" role or combination of ( "role1" and "permission1") is not true for theirs, don't allow to access that action method.
how i can do this scenario?
do claims based authorization useful in this manner?
or i must implement Permission entity and custom AuthorizeAttribute? if true how?
best regards
Check out the ResourceAuthorize attribute in the Thinktecture.IdentityModel.Owin.ResourceAuthorization.Mvc package.
This attribute authorizes a user based on an action (e.g. read) and a resource (e.g. contact details). You can then base whether or not they are allowed to perform that action on a resource based on a claim (e.g. their presence in a role).
See here for a good example.
Might not be exactly what you are looking for, but you can take inspiration and implement your own authorization attribute using similar logic.
This is custom made Authorize which checks permission from database.
For example you have 3 bools for permission Account,Clients,Configuration
and you want to restrict user based on them.
you can add even two permission on one action, for example you have a method which can be accessed by Account and Client permission than you can add following line
Modify this to use roles with permissions in this, this is the easiest and best way to handle it.
[PermissionBasedAuthorize("Client, Account")]
This method below is which check the bools from database.
public class PermissionBasedAuthorize : AuthorizeAttribute
{
private List<string> screen { get; set; }
public PermissionBasedAuthorize(string ScreenNames)
{
if (!string.IsNullOrEmpty(ScreenNames))
screen = ScreenNames.Split(',').ToList();
}
public override void OnAuthorization(HttpActionContext actionContext)
{
base.OnAuthorization(actionContext);
var UserId = HttpContext.Current.User.Identity.GetUserId();
ApplicationContext db = new ApplicationContext();
var Permissions = db.Permissions.Find(UserId);
if (screen == null || screen.Count() == 0)
{
actionContext.Response = new HttpResponseMessage(System.Net.HttpStatusCode.Unauthorized);
}
bool IsAllowed = false;
foreach (var item in screen)
foreach (var property in Permissions.GetType().GetProperties())
{
if (property.Name.ToLower().Equals(item.ToLower()))
{
bool Value = (bool)property.GetValue(Permissions, null);
if (Value)
{
IsAllowed = true;
}
break;
}
}
if (!IsAllowed)
{
actionContext.Response = new HttpResponseMessage(System.Net.HttpStatusCode.Unauthorized);
}
}
}
I implemented a Permission-based extension for Microsoft Identity 2 membership system. But in this extension, permissions and roles are related together. there is a many-to-many relation between them. Also you can have a complex authentication with combination of roles and permissions. I suppose it can help you to do permission based authentication.
You can do permission authentication in two ways:
First approach:
// GET: /Manage/Index
[AuthorizePermission(Name = "Show_Management", Description = "Show the Management Page.")]
public async Task<ActionResult> Index(ManageMessageId? message)
{
//...
}
Second approach:
// GET: /Manage/Users
public async Task<ActionResult> Users()
{
if (await HttpContext.AuthorizePermission(name: "AllUsers_Management", description: "Edit all of the users information."))
{
return View(db.GetAllUsers());
}
else if (await HttpContext.AuthorizePermission(name: "UnConfirmedUsers_Management", description: "Edit unconfirmed users information."))
{
return View(db.GetUnConfirmedUsers());
}
else
{
return View(new List<User>());
}
}
Also it's an open source and free extension and you can access to the repository here.
Here is my problem with my MVC 4 Internet project using Forms Authentication.
Lets say i have hotels and i want the authorized users accessing each under different roles.
So the user logs in. Then from a dropdownlist selects the target Hotel and the application´s security responds accordingly.
I would need something like [Authorize(Roles = "Administrator")] but only in that hotel scope.
My first aproach was inheriting from AuthorizeAttribute and override AuthorizeCore like is shown in this thread
From there I could get the HttpContext.Session["HotelId"] and query a UserRolesInHotel table. That said, I should have my own roles table with a structure similiar to UserId, RoleId, HotelId. So SimpleRolePrivider comes short to this task and i would be forced to create a CustomeRoleProvider. RoleProvider Methods don´t handle extra params as I need like HotelId when adding a new role to a user.
For clarification:
User A logs in with user/password ->OK (SimpleMembershipProvider)
Authenticated User A selects Hotel 1 -> User A is an "Administrator" for Hotel 1.
Authenticated User A change to Hotel 2 -> User A is a "User" in Hotel 2
I can have any number of hotels.
User A -> Hotel 1 -> { "Administrator", "User"}
User A -> Hotel 2 -> { "User" }
User A -> Hotel 3 -> { "Owner" }
User A -> Hotel 4 -> { "Administrator" }
The list of roles is always the same.
I´ve been struggling with this implementation for a couple of days and i couldn´t come up with a pratical solution.
Any thougths would be much appreciated.
Thanks!
This is what I did:
Added a DefaultBuildingId to the user profile.
Then I created a CustomRoleProvider and overrided GetRolesForUser method like this
public override string[] GetRolesForUser(string userName)
{
if (HttpContext.Current.Session != null)
{
var user = _userRepository.GetByName(userName);
if (!user.IsActive)
{
throw new ApplicationException(string.Format("some message {0}", userName));
}
if (HttpContext.Current.Session["BuildingId"] == null)
{
var building = _buildingRepository.Get(user.DefaultBuildingId);
if (building == null)
{
throw new ApplicationException("error message");
}
HttpContext.Current.Session["BuildingId"] = building.BuildingId;
}
int buildingId = Convert.ToInt32(HttpContext.Current.Session["BuildingId"]);
return _userRepository.GetRolesForUserInBuilding(user.UserId, buildingId).ToArray();
}
throw new ApplicationException("error message.");
}
Added a custom AuthorizeAttribute
protected override bool AuthorizeCore(HttpContextBase httpContext)
{
var authorized = base.AuthorizeCore(httpContext);
if (!authorized)
{
return false;
}
var repo = UnityManager.Resolve<IUserRepository>();
var buildingId = (int)httpContext.Session["BuildingId"];
var userName = httpContext.User.Identity.Name;
var user = repo.GetByName(userName);
var userRolesInBuilding = repo.GetRolesForUserInBuilding(user.UserId, buildingId);
foreach (var role in Roles.Split(','))
{
if (userRolesInBuilding.Contains(role.Trim()))
{
return true;
}
}
return false;
}
And finally this is how to use it at controller or action level.
[BuildingAthorize(Roles = "Administrators")]
I also added a ddl to the layout to let the user change the building and set the new BuildingId overriding the value at the session/db. This way a user can work in different Hotels during the same session and only access areas and functionality he has for that particular hotel.
Greetings,
can someone give me some advices or links that will help me to implement to following scenario.
Page will be written in asp.net mvc. Authorization is going to be implemented by Memberships. The scenario is as follows:
User1 has just logged in. After a
while, User2 attempts to login with
success. Then user1 should be notified
that User2 has just logged in. Additionally User2
should be notified that User1 is
online.
How can I achieve something like that? It should also be possible for these users to write messages to each other. (chat like).
There are methods to do this in the asp.net membership providers, specifically, IsUserOnline() and something like CountUsersOnline(). The only problem with these methods is that they are really lame. They depend on the membership provider's LastActivityDate() and a window you can set in web.config. In other words, the user is considered online if his last encounter with the membership provider plus the time window in web.config has not expired.
We took this scenairo and made it work for us by setting up a Comet server, and pinging the Web server every ten minutes. When the Web server is pinged, it updates the LastActivityDate of the membership provider.
We set the activity window to 12 minutes, as well as the Session timer. This allows us to determine who is online to an accuracy of aproximately ten minutes.
Here is the line in Web.config:
<membership userIsOnlineTimeWindow="12">
Here is jQuery Comet server:
function getData() {
$.getJSON("/Account/Timer", gotData);
}
// Whenever a query stops, start a new one.
$(document).ajaxStop(getData, 600000);
// Start the first query.
getData();
Here's our server code:
public JsonResult Timer()
{
MembershipUser user = Membership.GetUser(User.Name);
user.LastActivityDate = DateTime.Now;
Membership.UpdateUser(user);
// You can return anything to reset the timer.
return Json(new { Timer = "reset" }, JsonRequestBehavior.AllowGet);
}
Sounds to me like you need some jQuery polling to happen.
You can easily do a jQuery post to an ActionResult which would then check for users online and returns a PartialView back to the calling jQuery function.
The returning PartialView might have all the users logged in which can then be popped up in some sort of animating panel.
Use javascript to execute a timed poll back to the controller.
You cannot get onlines live in web. you should refresh page or refresh content with ajax -or else-. So it gonna solve i think.
ps. chat and online issues, you have two options; you can store them in database -its what i suggest- or store in memory, you may want to look this
Tables:
Users
-Id / int - identity
-LoginTime / datetime
-IsOnline / bit
Friends
-Id / int - identity
-FirstUserId / int
-SecondUserId / int
public class UserInformation
{
public IList<User> OnlineFriends { get; set;}
public IList<User> JustLoggedFriends { get; set; } /* For notifications */
}
public class UserRepository
{
public UserInformation GetInformation(int id, DateTime lastCheck)
{
return Session.Linq<User>()
.Where(u => u.Id == id)
.Select(u => new {
User = u,
Friends = u.Friends.Where(f => f.FirstUser.Id == u.Id || f.SecondUser.Id == u.Id)
})
.Select(a => new UserInformation {
JustLoggedFriends = u.Friends.Where(f => f.IsOnline && f.OnlineTime >= lastCheck).ToList(),
OnlineFriends = u.Friends.Where(f => f.IsOnline).ToList()
})
.ToList();
}
}
public class UserService
{
public UserInformation GetInformation(int id, DateTime lastCheck)
{
return repository.GetInformation(id, lastCheck);
}
}
UI:
public class UserController
{
public ActionResult Index()
{
var userId = (int)Session["UserId"];
var lastCheck = (DateTime)Session["LastCheck"];
UserInformation info = userService.GetInformation(userId, lastCheck);
Session["LastCheck"] = DateTime.Now;
//show up notifications and online users.
}
public ActionResult Login()
{
User user = null; // TODO: get user by username and password
Session["UserId"] = user.Id;
Session["LastCheck"] = DateTime.Now;
}
}