When one registers a view in ZCML like:
<browser:page
for="*"
name="reporter"
class=".reporter.report_form_frame"
permission="cmf.SetOwnPassword"
/>
In which point of traversing stack Zope machinery checks for this permission
Which component keep track of views and their permissions
The browser:page handler sets the permission on the view class itself. There is no central component that keeps track.
In Zope 2, that is delegated to the AccessControl.security.protectClass() function, which is the equivalent of adding a ClassSecurityInfo object to your view class:
from AccessControl.SecurityInfo import ClassSecurityInfo
class report_form_name(BrowserView):
security = ClassSecurityInfo()
security.declareObjectProtected('cmf.SetOwnPassword')
or, if making the view public (zope.Public) or private (zope.Private), the security.declareObjectPublic() or security.declareObjectPrivate() calls are used instead.
The class security info is translated into a __roles__ and __ac_permissions__ attributes on the class that the publisher inspects when checking permissions. See the Security chapter of the Zope Secrets book for details on how those work.
Related
I am trying to create custom Health checks in AEM 6.
I have,
1)Created a java class that extends inbuilt HealthCheck class.
2)The class looks like,
//SlingHealthCheck properties
#SlingHealthCheck(
name="Annotated Health Check Sample",
mbeanName="annotatedHC",
description="Sample Health Check defined by a java annotation",
tags={"hcTest"})
//Component and service annotations
#Component
#Service(value=HealthCheck.class)
public class HealthCheckTestClass implements HealthCheck{
#Override
public Result execute() {
Result result = new Result(Status.CRITICAL,
"Hey Something went wrong!!");
return result;
}
}
3) I have created a bundle which contains this class.
4)I have installed it in AEM from web console.
I don't know how can I configure it so that I can see the output produced by my custom health check class on AEM web console?
You can take the source code of the Apache Sling Health Check Samples bundle as an example that creates some custom health checks.
All active HealthCheck services should be visible on the OSGi console page at /system/console/healthcheck, as well as from a JMX console. See the Sling Health Checks page for more details.
See the AEM Operations Dashboard documentation for how to add such active HealthCheck services to the AEM dashboard pages - as that page says it is necessary to insert entries in the Dashboard's configuration nodes to select what's displayed on those pages.
Is it possible in Symfony2 to configure a service by injecting data from another service? For example, by calling a getter on another service?
In my specific case I am creating a (reusable) service that can handle translatable entity fields. For this I need a list of available locales in the application. I have looked at some other bundles that also work with locales, but they always use a static array from the configuration. For example:
a2lix_translation_form:
locales: [en, fr, nl]
This configuration usually ends up mapping to the service in the form of a constructor parameter or setter via the bundle configuration. For example:
class SomeService {
function __construct(array $locales) { ... }
// or
function setLocales(array $locales) { ... }
}
But in my case the list of available locales is not always static and often comes from the database. I have created a Locale service in my application with a method getLocales that returns an array. But how do I get that array into my service that needs it?
The service I am creating that needs a list of locales is split off into a separate reusable bundle. I don't want to inject the Locale service directly because that service is specific to the application, and not the bundle I am creating. I want users of my bundle to be able to provide a static list of locales, or point towards a service that has all the locales.
I would solve this problem using semantic configuration and config defintions. It works pretty similar to how FOSUserBundle asks for a driver and uses different settings depending on your choice (orm, mongodb, propel).
You could add something like this to your config.yml:
a2lix_locale:
provider: default # database
# ... additional settings which are optional,
# but required by provider, e.g. database settings
Your bundle's Configuration.php would verify that a valid provider was selected and that additional settings are set according to what each provider requires. Again, FOSUserBundle provides a great example for how to do this.
Additionally in your bundle's MyBundleExtension.php in /DependencyInjection you can access the service container and pass for instance the parameter locale to your default service in order for it to use the application's default locale provided in parameters.yml.
I want to remove logged out user from a Hashmap I have for logged in users but I don't find the way to do this as when I press the logout link. It just redirected to login page.
In spring security I have
<logout invalidate-session="true"
logout-success-url="/"
logout-url="/logout.htm"/>
logout link is like
Logout
When I press this link it just go to my login mapping
#RequestMapping("login")
public ModelAndView login(){}
and when I try to get user detail using
SecurityContextHolder.getContext()
.getAuthentication().getPrincipal();
it returns me anonymous user. So how can I get the logged out user detail.
Please let me know if you need more details.
Add an implementation of org.springframework.security.web.authentication.logout.LogoutSuccessHandler interface as a bean to your security context.
Then you can use it:
<logout success-handler-ref="yourLogoutSuccessHandler" />
EDIT.
As mentioned by Marcel this solution will not work out of the box because you can't mix success-handler-ref and logout-success-url attributes (reference). I prefer slightly different solution : instead of inheritance, you can use composition:
Prepare configuratio for SimpleUrlLogoutSuccessHandler bean.
Set up logout-success-url via corresponding defaultTargetUrl property.
Inject SimpleUrlLogoutSuccessHandler bean into your CustomUrlLogoutSuccessHandler using LogoutSuccessHandler interface and call it after doing your stuff.
Advantage is that you will be less coupled with a framework code. So you will have less problems in a case of migration from Spring Security 3.1 to Spring Security Y.Y
The hint about the LogoutSuccessHandler is correct. However, you have to consider that configuring success-handler-ref and logout-success-url are mutually exclusive if I'm not mistaken. Hence, you need to implement the forwarding to URL manually in your success handler. Pointer: https://stackoverflow.com/a/6770785/131929
Authentication authentication = SecurityContextHolder.getContext().getAuthentication()
authentication.getName()
In your applicationContext-security.xml file add the success-handler like below
< logout logout-url="/resources/j_spring_security_logout" success-handler-ref="com.mycompany.security.SpringSecurityLogoutHandler" />
Create the Class which will be implemneting org.springframework.security.web.authentication.logout.LogoutHandler interface and in it's logout method do all the stuff you want at the time of logout.
My MVC application makes use of a User's Role in multiple places during individual page requests. My question is whether the default SqlRoleProvider caches the current User's Roles for the lifetime of a page-request?
For example, I make use of Roles in attributes on Controller methods:
[Authorize(Roles = "Admin")]
and custom code
if (user.IsInRole(MembershipRole.Admin))
{
// Do something
}
else if (user.IsInRole(MembershipRole.Printer))
{
// Do something else
}
If the Role Provider does not cache roles, is the best solution to write a custom Role Provider that inherits from the default one, and override the methods to get the Roles once and cache them for the Request duration? Can this be done in a way that both the Authorize attribute and my own code will make use of the cached roles?
(In case you were wondering, I don't want to use the cacheRolesInCookie web.config option to cache the roles in cookies).
Thanks in advance for any suggestions.
[Edit to include details triggered from Joe's answer]
I decompiled System.Web.Mvc.AuthorizeAttribute and the AuthorizeCore method calls the following method for each role to be checked:
httpContext.User.IsInRole
Then peering into System.Web.Security.RolePrincipal (which is what "User" is above) both the methods below do indeed use a cached copy of the User's roles (or populates the cache if empty):
public string[] GetRoles()
public bool IsInRole(string role)
The cache is stored as a field on User, so its lifetime is for the duration of the request.
The methods find the roles using:
Roles.Providers[this._ProviderName].GetRolesForUser(this.Identity.Name)
so will use whatever role provider you have chosen for the application (default or custom).
If you use a RoleProvider in an ASP.NET or ASP.NET MVC application, then HttpContext.User will reference a RolePrincipal which does cache roles for the lifetime of the request.
However, in a WCF service that uses ASP.NET roles:
<behavior ...>
<serviceAuthorization principalPermissionMode ="UseAspNetRoles"
roleProviderName ="MyRoleProvider" />
</behavior>
this is not true: instead HttpContext.User will reference the internal class System.ServiceModel.Security.RoleProviderPrincipal, which does not cache roles: instead it always calls RoleProvider.IsUserInRole.
The out-of-the-box RoleProviders don't do any caching, so this can result in repeated connections to the underlying data store. It seems like a deficiency to me: it would have been easy to cache the roles on first access.
is the best solution to write a custom Role Provider that inherits from the default one, and override the methods to get the Roles once and cache them for the Request duration?
Not necessary for ASP.NET or ASP.NET MVC, but could be envisaged for WCF. Caching for the Request duration will presumably use HttpContext.Items, so will introduce a dependency on the existence of HttpContext, but that's not necessarily a problem except for making unit testing harder.
Can this be done in a way that both the Authorize attribute and my own code will make use of the cached roles?
If you configure your custom RoleProvider in web.config there's nothing more you need to do so that the Authorize attribute will use it.
I'm using a portalsitemapprovider object to create my navigation server control.
I've assigned sharepoint object model access and impersonation rights in the controls CAS. However despite this I can't retrieve the child nodes of the root node of the sitemap, they just return an error.
If I change the web app to run under full trust I can retrive the child nodes.
Thus my question is what CAS policies are requried to fully access data in the sitemap provider object, and how come I can access the root node but not it's children currently?
Example code:
PortalSiteMapProvider sp = PortalSiteMapProvider.WebSiteMapProvider;
PortalSiteMapNode rootNode = (PortalSiteMapNode)siteProvider.RootNode;
foreach (SiteMapNode node in rootNode.ChildNodes)
{
//this loop returns 1 item with title "Error" with no exception thrown.
}
My Assembly has the following CAS requests:
[assembly: SharePointermission(SecurityAction.RequestMinimum, ObjectModel=true, Impersonate=true)]
With approprite IPermission entries in the deployment manifest. After deploying the web app web.config is updated to WSS_Custom trust level as expected.
Any ideas?
Thanks
You could try using Reflector. This should show you the CAS permissions on that class.
Or use WSPBuilder, which will use reflection to generate the CAS file for you. I recommend this option as you shouldn't need to worry about editing your CAS files again!