I would like to secure all my JSF pages with permissions.
E.g. portal/customerEdit.jsf can be open, only if the user has permission "customer:create".
Here is my current shiro-web.ini
# Using default form based security filter org.apache.shiro.web.filter.authc.FormAuthenticationFilter
authc = org.apache.shiro.web.filter.authc.FormAuthenticationFilter
authc.loginUrl = /common/login.jsf
authc.successUrl = /portal/dashboard.jsf
# Redirect to an access denied page if user does not have access rights
[roles]
roles.unauthorizedUrl = /common/access-denied.jsf
# Protected URLs
[urls]
/portal/customerEdit** = authc, perms["customer:create"]
/WEB-INF/layout/portal/** = authc
/portal/** = authc
/admin/** = authc
The security is working (user can open the page only, if he has the permission), but I got only a blank screen with a simple text..
What I would like to do is to redirect the user to a access-denied.jsf page (like I defined), but this is not working....
One information: I´m not using "roles"... All my roles are dynamic from the database...
Any idea how I can solve this, that the user will be redirect to the access-denied.jsf page?
You would want to set the unauthorizedUrl against the filter that you are using in your top section (not the roles section):
perms.unauthorizedUrl = ...
or set it globally with shiro.unauthorizedUrl
My guess is something like this would work:
# Using default form based security filter org.apache.shiro.web.filter.authc.FormAuthenticationFilter
authc = org.apache.shiro.web.filter.authc.FormAuthenticationFilter
authc.loginUrl = /common/login.jsf
authc.successUrl = /portal/dashboard.jsf
# Redirect to an access denied page if user does not have access rights
perms.unauthorizedUrl = /common/access-denied.jsf
# Protected URLs
[urls]
/portal/customerEdit** = authc, perms["customer:create"]
/WEB-INF/layout/portal/** = authc
/portal/** = authc
/admin/** = authc
Keep us posted!
Related
I have to customize sharepoint 2013 document set welcome page(document set properties web part) and
I am not able to find the document set home aspx page
Can I use any client context model to fetch the data and display doc set properties.
Just create a new content type inheriting from Document Set, add the extra columns and set which ones need to be shown on the welcome page via the Document Set settings link when editing the Content Type. Also under the Document Set settings page you can click on 'Customize the Welcome Page' which allows you to edit the page just like any other web part page.
On the second point the client context will need to be connected to the web that contains the list and specific document set you're after, the identity used to connect will need permissions to the document set.
Edit:
To customize the look and feel by injecting JavaScript/CSS you'll need to make use of the ScriptLink custom action.
This lets you inject a custom piece of JavaScript into all pages. In the script you'll need logic to determine if the custom CSS should be applied, and if so Inject it.
The C# for injecting a script block via ScriptLink Custom Action:
public void AddJsLink(ClientContext ctx, Web web)
{
string scenarioUrl = String.Format("{0}://{1}:{2}/Scripts", this.Request.Url.Scheme,
this.Request.Url.DnsSafeHost, this.Request.Url.Port);
string revision = Guid.NewGuid().ToString().Replace("-", "");
string jsLink = string.Format("{0}/{1}?rev={2}", scenarioUrl, "injectStyles.js", revision);
StringBuilder scripts = new StringBuilder(#"
var headID = document.getElementsByTagName('head')[0];
var");
scripts.AppendFormat(#"
newScript = document.createElement('script');
newScript.type = 'text/javascript';
newScript.src = '{0}';
headID.appendChild(newScript);", jsLink);
string scriptBlock = scripts.ToString();
var existingActions = web.UserCustomActions;
ctx.Load(existingActions);
ctx.ExecuteQuery();
var actions = existingActions.ToArray();
foreach (var action in actions)
{
if (action.Description == "injectnavigation" &&
action.Location == "ScriptLink")
{
action.DeleteObject();
ctx.ExecuteQuery();
}
}
var newAction = existingActions.Add();
newAction.Description = "injectnavigation";
newAction.Location = "ScriptLink";
newAction.ScriptBlock = scriptBlock;
newAction.Update();
ctx.Load(web, s => s.UserCustomActions);
ctx.ExecuteQuery();
}
Then your JavaScript would have something like:
if(window.location.href.indexOf(patternToMatchToDocSetpage)>-1) {
var link = document.createElement("link");
link.href = "http://example.com/mystyle.css";
link.type = "text/css";
link.rel = "stylesheet";
document.getElementsByTagName("head")[0].appendChild(link);
}
I'd advise you to take a look at the relevant PnP sample on script link injection
I am going crazy since two days solving an issue. The problem is;
I am making a console APP which is talking to SharePoint Online using global admin account (One which was specified as admin while making a new subscription). What I am trying to achieve is, I want to add a custom action using CSOM to each site collection and subsite of office 365. That code works fine except on the root site collection which is pre-created by office 365 while signing up (i.e. https://xyz.sharepoint.com)
For any tenant for root site collection, it gives me below error;
{
"SchemaVersion":"15.0.0.0","LibraryVersion":"16.0.3912.1201","ErrorInfo":{
"ErrorMessage":"Access denied. You do not have permission to perform
this action or access this
resource.","ErrorValue":null,"TraceCorrelationId":"2a47fd9c-c07b-1000-cfb7-cdffbe3ab83a","ErrorCode":-2147024891,"ErrorTypeName":"System.UnauthorizedAccessException"
},"TraceCorrelationId":"2a47fd9c-c07b-1000-cfb7-cdffbe3ab83a" }
Now the user is global admin. I also added again that user as site collection admin.
The same piece of code works fine on other site collections (search site collection, any newly made site collection...).
here is a code;
using (ClientContext spcollContext = new ClientContext(web.Url))
{
SecureString passWord = new SecureString();
foreach (char c in strAdminPassword.ToCharArray()) passWord.AppendChar(c);
SharePointOnlineCredentials creds = new SharePointOnlineCredentials(strAdminUser, passWord);
spcollContext.Credentials = creds;
Web currentweb = spcollContext.Web;
spcollContext.Load(currentweb);
spcollContext.ExecuteQuery();
// authCookie = creds.GetAuthenticationCookie(new Uri(web.Url));
var existingActions2 = currentweb.UserCustomActions;
spcollContext.Load(existingActions2);
spcollContext.ExecuteQuery();
var actions2 = existingActions2.ToArray();
foreach (var action in actions2)
{
if (action.Description == "CustomScriptCodeForEachsite" &&
action.Location == "ScriptLink")
{
action.DeleteObject();
spcollContext.ExecuteQuery();
}
}
var newAction2 = existingActions2.Add();
newAction2.Description = "CustomScriptCodeForEachsite";
newAction2.Location = "ScriptLink";
newAction2.ScriptBlock = scriptBlock;
newAction2.Update();
spcollContext.Load(currentweb, s => s.UserCustomActions);
spcollContext.ExecuteQuery(); // GETTING ERROR ON THIS LINE.
}
Note: Above error is Fiddler traces.
Most probably this behavior is caused by Custom Script feature, basically
the issue occurs when the Custom Script feature is turned off
How to verify?
You could verify the site permissions using the following console app:
using (var ctx = GetContext(webUri, userName, password))
{
var rootWeb = ctx.Site.RootWeb;
ctx.Load(rootWeb, w => w.EffectiveBasePermissions);
ctx.ExecuteQuery();
var permissions = rootWeb.EffectiveBasePermissions;
foreach (var permission in Enum.GetValues(typeof(PermissionKind)).Cast<PermissionKind>())
{
var permissionName = Enum.GetName(typeof(PermissionKind), permission);
var hasPermission = permissions.Has(permission);
Console.WriteLine("Permission: {0}, HasPermission: {1}", permissionName, hasPermission);
}
}
where
public static ClientContext GetContext(Uri webUri, string userName, string password)
{
var securePassword = new SecureString();
foreach (var ch in password) securePassword.AppendChar(ch);
return new ClientContext(webUri) {Credentials = new SharePointOnlineCredentials(userName, securePassword)};
}
When SP.PermissionKind.AddAndCustomizePages is set to False, the Access denied error occurs while adding user custom action.
Solution
According to Turn scripting capabilities on or off:
For self-service created sites, custom scripting is disabled by
default
Solution: enable Allow users to run custom scripts on self-service created sites
To enable or disable scripting from the SharePoint admin center
Sign in to Office 365 with your work or school account.
Go to the SharePoint admin center.
Select Settings.
Under Custom Script choose:
Prevent users from running custom script on personal sites or Allow
users to run custom script on personal sites.
Prevent users from running custom script on user created sites or
Allow users to run custom script on self-service created sites.
Select OK. It takes about 24 hours for the change to take
effect.
Since any change to the scripting setting made through the SharePoint Online admin center may take up to 24 hours to take effect, you could enable scripting on a particular site collection immediately via CSOM API (SharePoint Online Client Components SDK) as demonstrated below:
public static void DisableDenyAddAndCustomizePages(ClientContext ctx, string siteUrl)
{
var tenant = new Tenant(ctx);
var siteProperties = tenant.GetSitePropertiesByUrl(siteUrl, true);
ctx.Load(siteProperties);
ctx.ExecuteQuery();
siteProperties.DenyAddAndCustomizePages = DenyAddAndCustomizePagesStatus.Disabled;
var result = siteProperties.Update();
ctx.Load(result);
ctx.ExecuteQuery();
while (!result.IsComplete)
{
Thread.Sleep(result.PollingInterval);
ctx.Load(result);
ctx.ExecuteQuery();
}
}
Usage
using (var ctx = GetContext(webUri, userName, password))
{
using (var tenantAdminCtx = GetContext(tenantAdminUri, userName, password))
{
DisableDenyAddAndCustomizePages(tenantAdminCtx,webUri.ToString());
}
RegisterJQueryLibrary(ctx);
}
where
public static void RegisterJQueryLibrary(ClientContext context)
{
var actions = context.Site.UserCustomActions;
var action = actions.Add();
action.Location = "ScriptLink";
action.ScriptSrc = "~SiteCollection/Style Library/Scripts/jQuery/jquery.min.js";
action.Sequence = 1482;
action.Update();
context.ExecuteQuery();
}
If you don't have time for CSOM as described by Vadim, the page also links to a powershell script you can use:
Set-SPOsite <SiteURL> -DenyAddAndCustomizePages 0
But note that SiteUrl needs to be the admin url. If your tenant is https://mysite.sharepoint.com, the url you use is https://mysite-admin.sharepoint.com"
In our case, we were in the midst of a deployment when this hit and could not wait 24 hours (or even one hour!) to continue. Everything had been fine in our testing site collections, but when we deployed to the tenant root, we hit the error described above and this script fixed it. Apparently the feature is turned off by default on the tenant root.
Current site is not a tenant administration site
Turn scripting capabilities on or off
My first response would be that you shouldn't add a CustomAction on the fly through code. That said, I'm sure you have a good reason to need to do so.
Try to set the AllowUnsafeUpdates flag on SPWeb to true as soon as you reference currentWeb. Make sure to also set it back to false after you call the final ExecuteQuery()
By default, AllowUnsafeUpdates is false. It is used to block cross-site scripting attacks.
https://msdn.microsoft.com/en-us/library/Microsoft.SharePoint.SPWeb_properties.aspx
I am building module to register customers and after registration i need to redirect the user to home page (default). I cant see a way as in Orchard everything works as content items.
Some of my code from Controller is given below
$ if (!ModelState.IsValid)
return new ShapeResult(this, _services.New.Checkout_Signup(Signup: signup));
var customer = _customerService.CreateCustomer(signup.Email, signup.Password);
customer.FirstName = signup.FirstName;
customer.LastName = signup.LastName;
customer.Title = signup.Title;
_authenticationService.SignIn(customer.User, true);
return Redirect("~/Home Page URL here...");
In Orchard, the home page has an empty string for its alias. It's possible to look up the RouteValueDictionary of an alias by calling the IAliasService.Get() method. Once you have this, you can simply pass it to RedirectToRoute().
So for the home page:
var homepage = _aliasService.Get(String.Empty);
return RedirectToRoute(homepage);
You can see Orchard using this mechanism to check the home page in the AutoroutePartDriver.cs file lines 66 - 72 in version 1.7.2.
I have an account that has been persisted in a database using the User Principal Name (UPN) format: jdoe#domain.gobalx.com
I am working in a SharePoint environment that is Claims authenticated using the UPN format.
My problem is I need to get a UserProfile object for the persisted UPN account. I have tried the following but it doesn't work:
string upnAccount = "jdoe#domain.globalx.com";
SPServiceContext ctx = SPServiceContext.GetContext(SPContext.Current.Site);
UserProfileManager upm = new UserProfileManager(ctx);
UserProfile user = upm.GetUserProfile(upnAccount);
I keep getting: Microsoft.Office.Server.UserProfiles.UserNotFoundException: An error was encountered while retrieving the user profile
Does this mean that I have to convert the UPN account into a claim, and if so does anyone have an example on how to do that?
UserProfileManager UPM = null;
using (SPSite site = new SPSite(SPContext.Current.Web.Url))
{
using (SPWeb web = site.OpenWeb())
{
ServerContext serverContext = ServerContext.GetContext(site);
UPM = new UserProfileManager(serverContext);
foreach (UserProfile profile in UPM)
{
an = profile["AccountName"].Value;
title = profile["Title"].Value;
}
}
}
U can try this for get All userprofile. In foreach loop u can check for your fields and get perticular user details
In some cases under SharePoint sites with federated authentication there are no user profiles automatically created until you haven't setup synchronization. For this issue you may check if there already exists user profile for jdoe#domain.globalx.com via Central Admin.
Also your code must be run under impersonation, check the log for exception and try to use SPSecurity.RunWithElevatedPrivileges.
I am using form base authentication in my Sharepoint site. On my login page there are custom fields to be filled by unauthenticated user. These fields i want to add in to my list. I am using following code to insert record in list.
protected void AddVendor(object sender, EventArgs e)
{
string strList = "http://comp01:5353/Lists/Vendors/";
using (SPSite site = new SPSite(strList))
{
site.AllowUnsafeUpdates = true;
using (SPWeb web = site.OpenWeb())
{
web.AllowUnsafeUpdates = true;
SPUser user = web.AllUsers["demouser"];
SPList list = web.Lists["Vendors"];
SPListItem Item = list.Items.Add();
Item["First Name"] = txtVendorName.Text;
Item["Last Name"] = txtVLastName.Text;
Item["business"] = txtDescription.Text;
Item["Description"] = txtDescription.Text;
Item["Mobile No"] = txtMobileNumber.Text;
Item["Approved"] = "No";
Item["Created By"] = "demoadmin";
Item["Modified By"] = "demoadmin";
Item.Update();
}
}
}
but is is giving me an error saying that Thread was being aborted. I don't know what exactly missing. but is it because I am performing add action and user is not authenticated...?
I don´t know if it will help you but the code that says (f.e.) Item["Modified By"] will not work since that is the internal name which is Modified_x0020_By. This goes for all the fields with "spaces" in them.
This might be one of your issues...
Where have you written this code, is it inside some event ? Login Control Provides two events that will help you to solve this
OnLoginError="OnLoginError" OnLoggedIn="OnLoggedIn"
I did similar functionality where I wanted to capture the user name loggin to the site and log it to the DB Table. And with respect to the ThreadAbort Exception, it happens when you use Response.Redirect while a code is being executed. In you case I doubt that its being thrown because you are trying to do the above code but the FBA system tries to redirect the user to the default.aspx . Try out above said Event of the Login Control it should help you.