Spring Security 3 - Add information to (role) voters - spring

I am pretty new to Spring security and just going through the reference, doing some examples. One feature that I am strongly missing (and I wonder that hardly anybody else seems to miss it) is to provide custom information to the user why or for what reason access was denied. E.g. I would like to inform the user that he has no access to module A or that he needs to needs to be granted role-access B, etc.
I took at a look at the role interface, but this information seems to get lost:
int vote(Authentication authentication, Object object, List<ConfigAttribute> config);
Spring Security Access Denied logging with missing role
This says, that I have to provide a custom implementation of AccessDecisionManager.
But how could an actual implementation look like which provides specific information if access is denied? And how to hook it into spring security?
For starters simple role-based access would be sufficient. Can anybody provide any examples on this?

Have a look at the AffirmativeBased - DecisionManager. You can enhance it an add some additional information to the AccessDeniedException.
But it seams to be not so easy to get the reasons from the Voters why they dendied the access. (I hope you will find some naming pattern, or you have even to extend the voters).
And this is an example how to configure your custom DecisionManager
<security:http auto-config="true" access-decision-manager-ref="myDecisionManager">
<bean id="myAccessDecisionManager"
class="MyAffirmativeBasedDecisionManager">
<constructor-arg name="decisionVoters">
<list>
<ref bean="roleVoter" />
<ref bean="authenticatedVoter" />
<ref bean="preAdviceVoter" />
</list>
</constructor-arg>
</bean>
<bean id="roleVoter" class="org.springframework.security.access.vote.RoleVoter" />
<bean id="authenticatedVoter"
class="org.springframework.security.access.vote.AuthenticatedVoter" />
<bean id="preAdviceVoter"
class="org.springframework.security.access.prepost.PreInvocationAuthorizationAdviceVoter">
<constructor-arg ref="exprPreInvocationAdvice" />
</bean>
<bean
class="org.springframework.security.access.expression.method.ExpressionBasedPreInvocationAdvice"
id="exprPreInvocationAdvice">
<property name="expressionHandler" ref="methodExprHandler" />
</bean>
<bean id="methodExprHandler"
class="org.springframework.security.access.expression.method.ExtensibleMethodSecurityExpressionHandler">
<property name="methodSecurityExpressionRootFactory">
<bean
class="com.queomedia.infrastructure.security.spring.MethodSecurityExpressionRootFactoryImpl" />
</property>
</bean>

Related

LDAP: error code 1 - The directory server could not find a network group for the bind dn ""

Am Developing an application in Spring MVC with Spring Security. Now Integrating the OUD (Oracle Unified Directory) through LDAP. User authentication is working perfectly but the response from the LDAP and OUD is
Mapping between application and LDAP
<bean id="contextSource"
class="org.springframework.security.ldap.DefaultSpringSecurityContextSource">
<constructor-arg value="ldaps://192.196.0.182:1636/O=company"/>
</bean>
<bean id="ldapAuthProvider"
class="org.springframework.security.ldap.authentication.LdapAuthenticationProvider" >
<constructor-arg>
<bean class="in.web.service.impl.CustomLdapBindAuthenticator">
<constructor-arg ref="contextSource"/>
<property name="userDnPatterns">
<list>
<value>cn={0},ou=groups</value>
</list>
</property>
</bean>
</constructor-arg>
<constructor-arg>
<bean class="in.web.service.impl.CustomLdapUserAuthoritiesPopulator">
</bean>
</constructor-arg>
</bean>
My observations
Since the application can able to find the users I assume configurations are correct
Since the LDAP error code is 1 (Is there any possibility for error in OUD setup)
it seems to be, bind dn is missing.
bind dn is your admin account/a user with required permissions, which you use to communicate with OUD.
Your configuration does not have any traces of this.

Spring Security LDAP - Problems Authenticating a User - Container Issue?

Let me preface this by saying I'm not well versed in Spring. I was thrown into a project at work and am trying to spin up as quickly as possible
With that in mind, I'm trying to implement spring security using Jasig's CAS and LDAP.
When I had loaded this set up from a local LDAP, things worked fine. However, since I've relocated it to the corporate LDAP, the webapp is no longer working.
At the moment, I can confirm this script successfully logs into LDAP and verifies the paths to the containers, however I get a server error before the page loads.
Code:
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:sec="http://www.springframework.org/schema/security" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd" >
<bean id="contextSource" class="org.springframework.security.ldap.DefaultSpringSecurityContextSource">
<!-- The URL of the ldap server, along with the base path that all other ldap path will be relative to -->
<constructor-arg value="ldaps://141.161.99.74:636/dc=testing,dc=com"/>
<property name="userDn" value="uid=OdinAdmin,ou=Specials,dc=testing,dc=com" />
<property name="password" value="testpw" />
</bean>
<bean id="ldapAuthProvider" class="org.springframework.security.ldap.authentication.LdapAuthenticationProvider">
<constructor-arg>
<bean class="org.springframework.security.ldap.authentication.BindAuthenticator">
<constructor-arg ref="contextSource"/>
<property name="userSearch" ref="ldapUserSearch"/>
</bean>
</constructor-arg>
<constructor-arg ref="authoritiesPopulator" /> <!-- Populates authorities in the UserDetails object -->
<property name="userDetailsContextMapper" ref="userDetailsMapper" /> <!-- Adds OWF groups to the UserDetails object -->
</bean>
<bean id="authoritiesPopulator" class="org.springframework.security.ldap.userdetails.DefaultLdapAuthoritiesPopulator">
<constructor-arg ref="contextSource"/>
<constructor-arg value="ou=OdinRoles,ou=Odin,ou=Apps"/> <!-- search base for determining what roles a user has -->
<property name="groupRoleAttribute" value="cn"/>
<!-- the following properties are shown with their default values -->
<property name="rolePrefix" value="ROLE_"/>
<property name="convertToUpperCase" value="true"/>
<property name="searchSubtree" value="true"/>
</bean>
<bean id="ldapUserSearch" class="org.springframework.security.ldap.search.FilterBasedLdapUserSearch">
<constructor-arg value="ou=people" /> <!-- search base for finding User records -->
<constructor-arg value="(uid={0})" /> <!-- filter applied to entities under the search base in order to find a given user.
this default searches for an entity with a matching uid -->
<constructor-arg ref="contextSource" />
</bean>
<!-- Custom class that goes back to the ldap database to search for OWF group records and also adds
extra attributes from the user's ldap record to the UserDetails object.
The class implementation of this will likely need to be changed out for differnt setups -->
<bean id="userDetailsMapper" class="ozone.securitysample.authentication.ldap.OWFUserDetailsContextMapper">
<constructor-arg ref="contextSource" />
<constructor-arg value="ou=OdinGroups,ou=Odin,ou=Apps" /> <!-- search base for finding OWF group membership -->
<constructor-arg value="(uniqueMember={0})" /> <!-- filter that matches only groups that have the given username listed
as a "member" attribute -->
<property name="searchSubtree" value="true"/>
</bean>
<bean id="ldapUserService" class="org.springframework.security.ldap.userdetails.LdapUserDetailsService">
<constructor-arg ref="ldapUserSearch" />
<constructor-arg ref="authoritiesPopulator" />
<property name="userDetailsMapper" ref="userDetailsMapper" />
</bean>
</beans>
My question is, am I allowed to have the subcontainers in the constructor-arg values for group and role searches? In my previous version, everything was in the same container. That way I could just have all that included in my base-dn and just reference the specific OU within that. Ie. instead of
I'm not sure if that is causing the issue, but any insight would be greatly appreciated. Thanks!
Can you provide what exactly is the error you're getting and which part actually fails? There is quite a bit of configuration in there and it'd very much help us if we narrow it down to one error or so.
P.S: I wanted this to be a comment but I'm sorry, i'm not yet allowed to comment due to the restrictions of SO.
This issue actually was based on the application I was implementing. It required specific role names (ROLE_ADMIN, ROLE_USER) to function. I had to map the existing roles to these 2 through a custom Java class.
Thanks for the help!

Autowire HttpServletRequest? To solve Locale?

My current project requires a customized "System date", which means a system date and it's format defined in the i18n properties file. But the class dealing with it is a general utility class but not within the web layer. However the locale(to work out the date format) has to be retrieved from a HttpServletRequest object. I am thinking autowire a HttpServletRequest instance to that utility class. It seems break the design pattern but I guess it is piratical. However it doesn't work. So what is wrong with that and is there any better way to solve the Locale in any other layers in Spring?
Thanks in advance.
Wouldn't it be a lot more elegant to simply overload the utility-class to accept a Locale as parameter on the affected methods. Then you can retrieve the locale in your controller and pass it down to the utility.
I prefer you to use the Spring Framework's SessionLocaleResolver. It will change and store the locale in the session and hence you can get that at any point of code in the application.
Please refer the below mentioned configuration for the same. And also read the Spring Documentation for the same for the better understanding.
<mvc:interceptors>
<ref bean="localeChangeInterceptor"/>
</mvc:interceptors>
<bean id="localeChangeInterceptor" class="org.springframework.web.servlet.i18n.LocaleChangeInterceptor">
<property name="paramName" value="lang"/>
</bean>
<bean id="localeResolver" class="org.springframework.web.servlet.i18n.SessionLocaleResolver">
<property name="defaultLocale" value="en"/>
</bean>
<bean id="messageSource" class="org.springframework.context.support.ReloadableResourceBundleMessageSource">
<property name="basenames">
<list>
<value>/WEB-INF/i18n/labels</value>
<value>/WEB-INF/i18n/messages</value>
</list>
</property>
<property name="defaultEncoding" value="UTF-8"/>
</bean>
Hope this helps you. Cheers.

best approach for setting hibernate/spring project

I have a project with spring and hibernate in GWT,
I am using below applicationcontext.xml,
I was just looking for some best approach of making this file
like all the annotated classes below i.e entity.user, entity.secretQuestion and many more , they all get called when my application runs even if i don't need them , which i guess makes my application quite slow,
so is it possible that only the class which i am calling is getting load in applicationcontext.xml and if yes then would it be a better approach as well ?
<bean id="sessionFactory"
class="org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean">
<property name="dataSource" ref="dataSource" />
<property name="annotatedClasses">
<list>
<value>com.cricsite.persistence.entity.User</value>
<value>com.cricsite.persistence.entity.SecretQuestion</value>
</list>
</property>
</bean>
<bean id ="ManagerAdmin" class= "com.persistence.MySQLRdbHelper">
<property name="sessionFactory" ref="sessionFactory" />
</bean>
You might be looking for something called "lazy loading"
Please take a look at these threads;
Help needed with Spring/Hibernate Lazy-loading
What is lazy loading in Hibernate?
how does spring allow for lazy-loading?

Spring-Security Spring-LDAP bind with Active Directory using sAMAccountName attribute

I have set up authentication against LDAP/AD and it is working fine. But now I wonder if it is possible to bind against Active Directory using the sAMAccountNAme attribute in the userDNPattern?
Since some AD configuration prevents unauthenticated users to search, and I can't ask for a user in order to configure the context bean, I can't define a org.springframework.security.ldap.search.FilterBasedLdapUserSearch bean like:
<bean id="userSearch"
class="org.springframework.security.ldap.search.FilterBasedLdapUserSearch">
<constructor-arg>
<value></value>
</constructor-arg>
<constructor-arg>
<value>(sAMAccountName={0})</value>
</constructor-arg>
<constructor-arg ref="contextSource" />
<property name="searchSubtree">
<value>true</value>
</property>
</bean>
Which would be enough.
Is there any work around?
Use Spring Security 3.1, It has built-in AD support.

Resources