Request of : /myProjectName/person/myProfile/
is ignored(ie I can access it when I should not) by:
<security:intercept-url pattern="/person/myProfile" access="isAuthenticated()"/>
However if I write:
<security:intercept-url pattern="/person/**" access="isAuthenticated()"/>
it works.
I have controller with handler mapping:
#RequestMapping("/person")
and inside of this controller I have method with handler mapping:
#RequestMapping(value= "/myProfile")
I don't understand it at all. I don't want to put "/person/**" as I will restrict other handler methods which should be available to anonymous. :-(
The issue was with understanding requests.
First: case does not matter as it is lowercased automatically unless explicitly stated not to.
Second: if you are control freak like me and like to protect every possible request manually make sure to have distinction between /request and /request/ as Spring security treat them separately(allowing second) - if we write...
<security:intercept-url pattern="/request" access="isAuthenticated()"/>
HOWEVER if we write:
<security:intercept-url pattern="/request/**" access="isAuthenticated()"/>
We protect both types, so in my case I should've put
<security:intercept-url pattern="/person/myProfile/**" access="isAuthenticated()"/>
Good day and be careful ;-) mine was especially ugly as it started to access fields that would throw exception if access was unauthorised.
Related
I have an xforms instance that I have a number of binds set up for so I can warn a user about input errors.
When he is done he needs to be able to submit the data from the instance. I would like to toggle 'active' on the button depending on whether or not the instance is valid.
What's the best way to 'attack' this problem? I'm currently using a group around the button that basically repeats what the model bindings already said which feels redundant and is error prone because of out of sync logic.
Also: this instance has 3 bindings, but I have others with 30-40 bindings.
Current code:
<xforms:group ref=".[instance('new-terminology-association')[matches(#code,'^\S+$')][matches(#codeSystem,'^[0-2](\.(0|[1-9][0-9]*))*$')][string-length(#displayName)>0]]">
<fr:button>
<xforms:label ref="$resources/create-association"/>
<xforms:action ev:event="DOMActivate">
...
</xforms:action>
</fr:button>
</xforms:group>
You could use the xxf:valid() function, pointing to the nodes you want to be valid. You can also point that function to a "parent" node, and ask it to check everything "under" that node is valid.
I think that function does what you're looking for, but because field values are only sent when users stab out of the field, this can create a somewhat unexpected user experience. For instance, imagine that the last field of your form, showing just before your button, is required. The user focuses on that field, and types a value. At this point the button is still disabled, since the value hasn't been sent to the server yet. Now the user hits tab, the value is sent to the server, the button would become enabled when the Ajax responses received, but since the button wasn't enabled at the time tab was pressed, the focus goes on something other than the button, which is somewhat unexpected. So, this is something to keep in mind.
There is absolutely no way in Orbeon 4.7 to make the button/trigger respond directly to xxf:valid. This looks like a bug to me. Workaround code: add observer for xxforms-valid and xxforms-invalid that set true|false in a new instance. Add readonly binding based on ".='false'" for that instance and use ref="instance" on the trigger. On a busy form with lots of buttons that is a bit of a waste, but it'll have to make due. Thanks for you help, appreciated!
<xf:instance id="button-control">
<button btn-term-add="false"/>
</xf:instance>
<xf:action ev:event="xxforms-invalid" ev:observer="new-terminology-association">
<xf:setvalue ref="instance('button-control')/#btn-term-add" >false</xf:setvalue>
</xf:action>
<xf:action ev:event="xxforms-valid" ev:observer="new-terminology-association">
<xf:setvalue ref="instance('button-control')/#btn-term-add">true</xf:setvalue>
</xf:action>
<xf:bind nodeset="instance('button-control')">
<xf:bind ref="#btn-term-add" readonly=".='false'"/>
</xf:bind>
....
<xf:trigger ref="instance('button-control')/#btn-term-add">
....
</xf:trigger>
I've already searched via google and on stackoverflow, but could not find any similar problem to mine.
In my project I'm handling a ViewExpiredException properly and show a custom page to the user that the current session has timed out. This works great, but I want to do something BEFORE this message gets shown to the user. Actually I'm working with 2 different sessions here, one on the frontend side and one on the backend, so the idea is to NOT start a new backend session when the current one timed out.
Is there any possibility to fetch the ViewExpiredException while I'm inside the doFilter method, so I do not start a new backend session (simply because it is not needed)? Or is there any other way?
I already tried to fetch the current context via
FacesContext fc = FacesContext.getCurrentInstance();
But obviously the context is null, because the session timed out.
Inside the ExceptionHandlerWrapper I have access to the UnhandledExceptionQueuedEvents, but this does not help me here since I need this information earlier.
I hope I made my problem clear enough.
Thanks in advance for any help!
Regards
Sebastian
Generally ViewExpiredException is thrown when a POST request is fired while the session is timed out. So, this should do in the filter:
boolean post = "POST".equals(request.getMethod());
boolean timedout = request.getRequestedSessionId() != null && !request.isRequestedSessionIdValid();
if (post && timedout) {
// JSF will guaranteed throw ViewExpiredException when state saving is set to server.
}
But this does not cover all possible cases. ViewExpiredException can also occur when the session hasn't timed out. For example, when the client has passed an invalid javax.faces.ViewState parameter, or when the associated view has been pruned from the LRU map which can by default hold 15 views. This is however not detectable inside a servlet filter before FilterChain#doFilter() is called. You really need to be inside the JSF context. You could do the backend session creating job in a PhaseListener. E.g. in beforephase of apply request values phase, which is guaranteed to be invoked only when there's a vaild view.
By the way, the FacesContext is not null in the filter because the session has timed out, but because the FacesServlet, the one responsible for creating it, hasn't been invoked yet at that point. You know, filters run before servlets.
I can use Spring Security ACL with permissions on entity but I'd like to know how to test if a user has access to the "create" (bit 2) permission on a class.
Something like :
aclPermissionEvaluator.hasPermission(auth, clazz, "create")
Could someone help me?
Thanks in advance
You can use Spring's SpEL annotations, e.g. #PreAuthorize, and override the hasPermission method of the PermissionEvaluator interface. If you're using bitwise permission masks, and the user's permissions (as an int) evaluate to '15' (1111), and the required permissions for the object are '6' (0110), you can do something like the following:
public boolean hasPermission(Authentication auth, Object targetObject, Object requiredPermissions) {
int permissionMask = MyUserClass.getMask();
int permissionsRequired = Integer.valueOf(requiredPermissions.toString());
return ((permissionMask | requiredPermissions) == permissionMask);
}
This will return true whenever the bits active in the object's permissions mask are active on the user's permissions. Then, you'd need to declare this custom permission evaluator in your security.xml file:
<security:global-method-security pre-post-annotations="enabled">
<security:expression-handler ref="expressionHandler"/>
</security:global-method-security>
<bean id="expressionHandler" class="org.springframework.security.access.expression.method.DefaultMethodSecurityExpressionHandler">
<property name="permissionEvaluator" ref="permissionEvaluator"/>
</bean>
<bean id="permissionEvaluator" class="my.project.package.CustomPermissionEvaluator"/>
Now, whenever you call hasPermission(), your custom evaluator will handle the request. Obviously, you can use whatever logic you like to evaluate permissions -- just make sure the return type is boolean, and the parameters to be passed match what you're sending (or evaluating against; be careful of format exceptions).
Note that your custom parameter must be passed as an Object to override hasPermission(); you could also overload the method by changing the signature to handle whatever parameter type you prefer (e.g. String or int), and the compiler should select the most specific signature. Since you're implementing the PermissionEvaluator interface, however, you'll have to include the given signature (Authentication, Object, Object) anyway, so unless you have some specific need to write an overload method, you may as well just override.
I have exactly the same problem, and sadly, there is no "out of the box" solutions.
One way to do it, if your domain model allow for it, is to add the create permission to the parent object you want to create
For example, imagine you want to create an user for a client. You can add the create permission to the client for the user allowed to create user for this specific client. That the path I choose.
If your domain object doesn't allow for that, the only way I found to do it is:
to create a new table acl_class_entry, wich list acl_entry equivalent but linked to an acl_class and not to an acl_object_identity
Then you create your own permission evaluator, surcharging the method boolean hasPermission(Authentication authentication, Serializable targetId, String targetType, Object permission) to check the permission against the acl_class_entry if target_id is null. This will allow you to check permission against a class by using the SPel expression hasPermission(nulll, 'className', 'permission')
Of course, you will also need to create your own version of AclService for creating such permission.
In two other questions (here and here) BalusC makes a straight up declaration:
Getters are solely there to access bean properties, not to do some business logic. There you have the bean constructor, initialization blocks or event methods for. All are executed only once during bean's life and that's exactly what you want.
Well gee -- this just invalidated a gazillion lines of code I have already written. Ok, then, what is the correct way of implementing a backing bean that fills a data table? I understand his point and the concept, but not the practice. My question is twofold:
Why is the way I am doing it wrong?
How do I fix it?
I use PrimeFaces p:dataTable a lot, and it's value attribute resolves to a collection. For reasons I don't go into here, I do not use PrimeFaces' lazy table loading feature. Instead I implement my own filter/sort controls, but they trigger AJAX events, which then results in the table being filled with records fetched from the data base.
The table is marked up like this:
<p:panel id="mqTable">
<h:outputText value="Sort/Filter: #{maintCategory.tableQueryParameters}" />
<p:dataTable
id="mqDataTable"
rows="#{maintCategory.pageSize}"
value="#{maintCategory.dataModel}"
selection="#{maintCategory.selected}"
var="cat"
selectionMode="single"
emptyMessage="No Categories Found">
Now the INCREDIBLY BAD UN-JSFish (or so I just found out) getter for dataModel goes like this:
public ATMDataModel getDataModel() {
TableQueryParameters p = getTableQueryParameters();
if (p.isChangePending()) clearDataModel();
p.setChangePending(false);
if (dataModel != null) return dataModel;
List<ET> list = getDAO().runQuery(p);
if (p.isNeedResultSize()) p.setResultSize(getDAO().runQueryCount(p));
dataModel = new ATMDataModel(list);
return dataModel;
}
A few explanations.
This is from an abstract super-class where ET is the "Entity Type." All my CRUDs use this same routine.
The class ATMDataModel is a wrapper for the list which implements SelectableListModel. The row selection logic in PrimeFaces requires this. (It is a pain that appeared in PF 3 but it makes row selection work more reliably.)
The class TableQueryParameters is something I wrote to encapsulate the current state of the table on the user's screen. It includes what sort parameters, what filter parameters, what page we are on, etc. Because this needs to be preserved, the backing bean is ViewAccesScoped (via MyFaces CODI) and the TableQueryParameters is a property within it.
The TableQueryParameters are updated in response via AJAX events, which also update the form causing getDataModel to be called. The method isChangePending goes true when anything changes. So the getDataModel method uses this to generate only one fetch from the DAO between changes no matter how many times it is called.
BUT if the TableQueryParameters do change, I have to call runQuery with those parameters to fetch the new set of records the user wants to see. If I don't call it in getDataModel where do I call it?
Please advise.
You're basically lazily loading the data in the getter. You're not hitting the DB on every getter call within the same request (or view) scope. This is affordable. I don't use CODI, but I'd imagine that the getTableQueryParameters() call is also particularly cheap and nothing to worry about.
As to the concrete question, you'd normally do the DB/business job in an action(listener) method which is attached to the UICommand component and/or the ajax event tag.
For example (works also as <p:commandButton action> though)
<p:ajax listener="#{bean.deleteSelectedRow}" />
...
<p:ajax listener="#{bean.saveRowDetail}" />
with
public void deleteSelectedRow() {
someService.delete(selectedRow);
dataModel = loadDataModel();
}
public void saveRowDetail() {
someService.save(selectedRow);
dataModel = loadDataModel();
}
Depending on the meaning of p.isChangePending(), I think you could also get rid of it this way, it look like that you were setting it in the action(listener) methods.
I need to detect if a request cookie - value is different from a response cookie - value.
Its not as easy as:
if(cookiesArePresent)
{
bool isDifferent = HttpContext.Current.Response.Cookies[".ASPXANONYMOUS"].value == HttpContext.Current.Response.Cookies[".ASPXANONYMOUS"].value;
}
But I read that changing the Response.Cookies changes the Request.Cookies. That would mean they are always the same if HttpContext.Current.Response.Cookies[".ASPXANONYMOUS"] was changed. Is there an easy way around this?
http://chance.lindseydev.com/2009/04/aspnet-httprequestcookies-and.html
If you use Reflector to examing System.Web.Security.AnonymousIdentificationModule, you can see that the anonymous cookie is only read/written in PostAuthenticateRequest.
So, if you suspect something is wonky, write a simple HttpModule that reads the cookie during AuthenticateRequest and compare it to the value you get in AuthorizeRequest.
For more information about the request lifecycle see Exploring Web.config - system.web/httpModules by yours truly.