i'm developping a webapp using SS for role managing. when i try to log in as admin it works fine,but the problem is when i want to log in as user it does too, which something i don't want to be. any ideas plz
this is my security-cpntext.xml
<beans:beans xmlns="http://www.springframework.org/schema/security"
xmlns:beans="http://www.springframework.org/schema/beans"
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
http://www.springframework.org/schema/security
http://www.springframework.org/schema/security/spring-security-3.1.xsd">
<!-- We will be defining all security related configurations in this file -->
<http pattern="/login" security="none" />
<http use-expressions="true" >
<intercept-url pattern="/login" access="IS_AUTHENTICATED_ANONYMOUSLY" />
<intercept-url pattern="/login" access="permitAll" />
<intercept-url pattern="/index" access="hasRole('Admin')"/>
<form-login login-page="/login" default-target-url="/index" authentication-failure-url="/login"/> <!-- We will just use the built-in form login page in Spring -->
<access-denied-handler error-page="/login" />
<!-- <intercept-url pattern="/**" access="isAuthenticated()"/> --><!-- this means all URL in this app will be checked if user is authenticated -->
<logout logout-url="/logout" logout-success-url="/index"/> <!-- the logout url we will use in JSP -->
</http>
<beans:bean id="daoAuthenticationProvider" class="org.springframework.security.authentication.dao.DaoAuthenticationProvider">
<beans:property name="userDetailsService" ref="userDetailsService" ></beans:property>
</beans:bean>
<beans:bean id="authenticationManager" class="org.springframework.security.authentication.ProviderManager">
<beans:property name="providers">
<beans:list>
<beans:ref local="daoAuthenticationProvider"/>
</beans:list>
</beans:property>
</beans:bean>
<authentication-manager>
<authentication-provider user-service-ref="userDetailsService">
<password-encoder hash="md5"></password-encoder>
</authentication-provider>
</authentication-manager>
I can see two potential issues here that may be causing the problem.
1) You're specifying hasRole('Admin') for /index. If the role name is called Admin then you should specify hasRole('ROLE_Admin').
2) You've got duplication in your configuration. The <authentication-manager> tells Spring security to create a ProviderManager instance. So you've declared this, but you've also manually specified the ProviderManager as a bean instance duplicating what <authentication-manager> does. Remove the following:
<beans:bean id="daoAuthenticationProvider" class="org.springframework.security.authentication.dao.DaoAuthenticationProvider">
<beans:property name="userDetailsService" ref="userDetailsService" ></beans:property>
</beans:bean>
<beans:bean id="authenticationManager" class="org.springframework.security.authentication.ProviderManager">
<beans:property name="providers">
<beans:list>
<beans:ref local="daoAuthenticationProvider"/>
</beans:list>
</beans:property>
</beans:bean>
And leave:
<authentication-manager>
<authentication-provider user-service-ref="userDetailsService">
<password-encoder hash="md5"></password-encoder>
</authentication-provider>
</authentication-manager>
Try that and see what you get.
Related
I'm trying to enable CORS on the Spring Security 4.2.3.RELEASE.
spring-mvc.xml
<mvc:mapping path="/rest/**"
allowed-origins="*"
allowed-methods="GET, POST, HEAD, OPTIONS, PUT, DELETE"
allowed-headers="Content-Type, X-Requested-With,accept, Origin,Access-Control-Request-Method, Access-Control-Request-Headers, Authorization"
exposed-headers="Access-Control-Allow-Origin,Access-Control-Allow-Credentials"
allow-credentials="false"
max-age="10" />
</mvc:cors>
spring-security.xml
<beans:beans xmlns="http://www.springframework.org/schema/security"
xmlns:beans="http://www.springframework.org/schema/beans"
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.xsd
http://www.springframework.org/schema/security
http://www.springframework.org/schema/security/spring-security.xsd">
<http pattern="/rest/**" use-expressions="true" entry-point-ref="unauthorizedEntryPoint" create-session="stateless">
<csrf disabled="true"/>
<cors/>
<custom-filter before="FORM_LOGIN_FILTER" ref="jwtAuthenticationFilter"/>
</http>
when try to deploy:
Caused by: org.springframework.beans.factory.BeanCreationException: Could not create CorsFilter
I was solving a similar issue. I tried several approaches and here is the setting that works best if anybody else needs it.
SpringSecurity: 4.2.0.RELEASE. All server's API calls are prefixed with /api/ path
Spring security context:
<http use-expressions='true'>
<!-- unrelated code skipped for brevity -->
<cors configuration-source-ref="corsSource"/>
</http>
<beans:bean id="corsSource" class="org.springframework.web.cors.UrlBasedCorsConfigurationSource">
<beans:property name="corsConfigurations">
<util:map>
<beans:entry key="/api/**">
<beans:bean class="org.springframework.web.cors.CorsConfiguration">
<beans:property name="allowCredentials" value="true"/>
<beans:property name="allowedHeaders">
<beans:list>
<beans:value>Authorization</beans:value>
<beans:value>Content-Type</beans:value>
</beans:list>
</beans:property>
<beans:property name="exposedHeaders">
<beans:list>
<beans:value>Account-Locked</beans:value>
<beans:value>Account-Disabled</beans:value>
<beans:value>Bad-Credentials</beans:value>
</beans:list>
</beans:property>
<beans:property name="allowedMethods">
<beans:list>
<beans:value>POST</beans:value>
<beans:value>GET</beans:value>
<beans:value>OPTIONS</beans:value>
</beans:list>
</beans:property>
<beans:property name="allowedOrigins" value="http://localhost:3000"/>
</beans:bean>
</beans:entry>
</util:map>
</beans:property>
</beans:bean>
And in my dispatcher-servlet.xml
<mvc:cors>
<mvc:mapping path="/api/**"
allowed-origins="http://localhost:3000"
allow-credentials="true"
allowed-methods="GET, OPTIONS"
/>
</mvc:cors>
Remember to change allowed-origins as well as allowedHeaders (= headers client is allowed to attach to request), exposedHeaders (= headers the server is allowed to attach to its response) and allowedMethods.
To keep sessions for authorized users I have to add allowCredentials property in Spring Security configuration and also to set withCredentials flag to true in JavaScript calls. I used axios so if you use another library, the flag may be named differently.
recently i have use Spring Security for my Spring MVC Web Admin. I Have a trouble when using Spring Security. When login process, always redirect to authentication-failure-url. I have my own UserDetailsServiceImpl that implements UserDetailsService (from Spring Security Feature).
This is my spring security
<!-- enable use-expressions -->
<http auto-config="true">
<intercept-url pattern="/*" access="permitAll" />
<intercept-url pattern="/resources/**" access="permitAll" />
<intercept-url pattern="/error" access="permitAll" />
<intercept-url pattern="/**" access="isAuthenticated()" />
<!-- access denied page -->
<access-denied-handler error-page="/403" />
<form-login login-page="/" default-target-url="/index"
always-use-default-target="false" authentication-failure-url="/error"
login-processing-url="/j_spring_security_check" username-parameter="j_username"
password-parameter="j_password" />
<logout logout-success-url="/"
delete-cookies="JSESSIONID,SPRING_SECURITY_REMEMBER_ME_COOKIE"
logout-url="/j_spring_security_logout" invalidate-session="true" />
<!-- enable csrf protection -->
<!-- csrf /-->
</http>
<global-method-security pre-post-annotations="enabled" />
<beans:bean id="customAuthenticationSuccessHandler"
class="com.mezzo.security.AuthenticationSuccessListener">
</beans:bean>
<beans:bean id="myAuthenticationSuccessHandler"
class="org.springframework.security.web.authentication.SavedRequestAwareAuthenticationSuccessHandler">
<beans:property name="defaultTargetUrl" value="/index" />
<!-- After login, return to the last visited page -->
<beans:property name="useReferer" value="true" />
</beans:bean>
<beans:bean id="userDetailsService"
class="com.mezzo.security.UserDetailsServiceImpl" />
<authentication-manager>
<authentication-provider user-service-ref="userDetailsService">
<password-encoder hash="md5" />
</authentication-provider>
</authentication-manager>
Please, what's the problem with my security config xml.
Thanks in Advance. :)
I am using Spring Security to authenticate against Active Directory using LDAP protocol. Following code works well in authentication and setting up LDAP templates too (springSecurity.xml) :
<?xml version="1.0" encoding="UTF-8"?>
<beans:beans xmlns="http://www.springframework.org/schema/security"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:beans="http://www.springframework.org/schema/beans"
xmlns:ldap="http://www.springframework.org/schema/ldap"
xsi:schemaLocation="
http://www.springframework.org/schema/security http://www.springframework.org/schema/security/spring-security-3.1.xsd
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.1.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd
http://www.springframework.org/schema/ldap
http://www.springframework.org/schema/ldap/spring-ldap.xsd">
<http use-expressions="true">
<intercept-url pattern="/login" access="permitAll" />
<intercept-url pattern="/authenticated" access="isAuthenticated()" />
<form-login login-page="/login" default-target-url="/authenticated"
authentication-failure-url="/login?error=true" />
<logout />
</http>
<beans:bean
class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<beans:property name="location">
<beans:value>classpath:/ldap.properties</beans:value>
</beans:property>
<beans:property name="SystemPropertiesMode">
<beans:value>2</beans:value> <!-- OVERRIDE is 2 -->
</beans:property>
</beans:bean>
<beans:bean id="adAuthenticationProvider"
class="org.springframework.security.ldap.authentication.ad.ActiveDirectoryLdapAuthenticationProvider">
<beans:constructor-arg value="${sample.ldap.domain}" />
<beans:constructor-arg value="${sample.ldap.url}" />
<beans:property name="useAuthenticationRequestCredentials"
value="true" />
<beans:property name="convertSubErrorCodesToExceptions"
value="true" />
</beans:bean>
<authentication-manager>
<authentication-provider ref="adAuthenticationProvider" />
</authentication-manager>
<!-- Ldap after authentication -->
<context:property-placeholder location="classpath:/ldap.properties"
system-properties-mode="OVERRIDE" />
<context:annotation-config />
<ldap:context-source id="contextSource"
password="${sample.ldap.password}"
url="${sample.ldap.url}"
username="${sample.ldap.userDn}"
base="${sample.ldap.base}"
referral="follow" />
<ldap:ldap-template id="ldapTemplate"
context-source-ref="contextSource" />
<ldap:repositories base-package="com.domain" />
<beans:bean class="com.service.UserService">
<beans:property name="directoryType" value="${sample.ldap.directory.type}" />
</beans:bean>
<!-- Required to make sure BaseLdapName is populated in UserService -->
<beans:bean
class="org.springframework.ldap.core.support.BaseLdapPathBeanPostProcessor" />
</beans:beans>
Authentication works fine while fetching j_username and j_password from login.jsp. To set up the ldap template i am using username and password attribute defined in properties file, but i wish to use same username and password from spring security. Please guide me as how to bind the Username and Password attribute properties in ldap:context-source id="contextSource" to spring security credentials.
The code is little messy, any input for improvement is welcomed.
As specified in the Configuration chapter of the reference documentation, you can use the Spring Security authentication for the ContextSource by specifying a custom authentication-source-ref in the the configuration element of the ContextSource. In your case you would use the a SpringSecurityAuthenticationSource, shipped with Spring Security.
<ldap:context-source id="contextSource"
url="${sample.ldap.url}"
base="${sample.ldap.base}"
referral="follow"
authentication-source-ref="authenticationSource"/>
<bean id="authenticationSource"
class="org.springframework.security.ldap.authentication.SpringSecurityAuthenticationSource" />
this is my spring-security.xml
<beans:beans xmlns="http://www.springframework.org/schema/security"
xmlns:beans="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:util="http://www.springframework.org/schema/util"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.2.xsd
http://www.springframework.org/schema/security
http://www.springframework.org/schema/security/spring-security-3.2.xsd
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.1.xsd
http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-3.1.xsd">
<http auto-config="true" use-expressions="true">
<intercept-url pattern="/admin**" access="hasRole('ROLE_ADMIN')" />
<intercept-url pattern="/signup" access="permitAll"></intercept-url>
<intercept-url pattern="/signin" access="permitAll"></intercept-url>
<intercept-url pattern="/logout" access="permitAll"></intercept-url>
<intercept-url pattern="/denied" access="permitAll"></intercept-url>
<intercept-url pattern="/**" access="isAuthenticated()"></intercept-url>
<access-denied-handler error-page="/403" />
<form-login login-page="/signin" default-target-url="/home"
authentication-failure-url="/denied" />
<logout logout-success-url="/logout"></logout>
</http>
<authentication-manager>
<authentication-provider>
<password-encoder ref="passwordEncoder" hash="sha-256"/>
<jdbc-user-service data-source-ref="dataSource"
users-by-username-query=
"select email,password, 'true' as enabled from user_login where email=? limit 1"
authorities-by-username-query=
"select email, role from user_roles where email =? " />
</authentication-provider>
</authentication-manager>
<beans:bean id="passwordEncoder" class="org.springframework.security.authentication.encoding.ShaPasswordEncoder">
<constructor-arg value="256"/>
</beans:bean>
</beans:beans>
i m getting this error as
cvc-complex-type.2.4.c: The matching wildcard is strict, but no declaration can be found for element 'constructor-arg'.
- Security namespace does not support decoration of element [constructor-arg]
- Configuration problem: Security namespace does not support decoration of element [constructor-arg] Offending resource: file (project path)
how can i solve this errror?
.i want to enocde the password and check if that matches with the database password.
I think the problem because beans is not the default namespace . So you could try
<beans:bean id="passwordEncoder" class="org.springframework.security.authentication.encoding.ShaPasswordEncoder">
<beans:constructor-arg value="256"/>
or declare beans as default namespace
<beans xmlns="http://www.springframework.org/schema/beans"
I have got spring security using kerberos authentication successfully working. But it seems the spring framework is invoking KerberosServiceAuthenticationProvider.userDetailsService to get the roles, I would have thought that it gets the roles only once until the session is invalidated. My config looks like
<?xml version="1.0" encoding="UTF-8"?>
<beans:beans xmlns="http://www.springframework.org/schema/security"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:util="http://www.springframework.org/schema/util"
xmlns:beans="http://www.springframework.org/schema/beans"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/util
http://www.springframework.org/schema/util/spring-util-3.0.xsd
http://www.springframework.org/schema/security
http://www.springframework.org/schema/security/spring-security-3.0.xsd">
<http entry-point-ref="spnegoEntryPoint" auto-config="false">
<intercept-url pattern="/login*" access="IS_AUTHENTICATED_ANONYMOUSLY" />
<intercept-url pattern="/j_spring_security_check*" access="IS_AUTHENTICATED_ANONYMOUSLY"/>
<intercept-url pattern="/**" access="IS_AUTHENTICATED_FULLY" />
<custom-filter ref="spnegoAuthenticationProcessingFilter" position="BASIC_AUTH_FILTER" />
<form-login login-page="/login.html" default-target-url="/" always-use-default-target="true"/>
</http>
<authentication-manager alias="authenticationManager">
<authentication-provider ref="kerberosServiceAuthenticationProvider" />
<authentication-provider ref="kerberosAuthenticationProvider"/>
</authentication-manager>
<beans:bean id="spnegoEntryPoint"
class="org.springframework.security.extensions.kerberos.web.SpnegoEntryPoint" />
<beans:bean id="spnegoAuthenticationProcessingFilter"
class="org.springframework.security.extensions.kerberos.web.SpnegoAuthenticationProcessingFilter">
<beans:property name="failureHandler">
<beans:bean class="org.springframework.security.web.authentication.ExceptionMappingAuthenticationFailureHandler">
<beans:property name="defaultFailureUrl" value="/login.html" />
<beans:property name="allowSessionCreation" value="true"/>
</beans:bean>
</beans:property>
<beans:property name="authenticationManager" ref="authenticationManager" />
</beans:bean>
<beans:bean id="kerberosServiceAuthenticationProvider"
class="org.springframework.security.extensions.kerberos.KerberosServiceAuthenticationProvider">
<beans:property name="ticketValidator">
<beans:bean
class="org.springframework.security.extensions.kerberos.SunJaasKerberosTicketValidator">
<beans:property name="servicePrincipal" value="HTTP/mywebserver.corpza.corp.co.za"/>
<beans:property name="keyTabLocation" value="classpath:mywebserver.keytab" />
<beans:property name="debug" value="true"/>
</beans:bean>
</beans:property>
<beans:property name="userDetailsService" ref="dummyUserDetailsService" />
</beans:bean>
<beans:bean id="kerberosAuthenticationProvider" class="org.springframework.security.extensions.kerberos.KerberosAuthenticationProvider">
<beans:property name="kerberosClient">
<beans:bean class="org.springframework.security.extensions.kerberos.SunJaasKerberosClient">
<beans:property name="debug" value="true" />
</beans:bean>
</beans:property>
<beans:property name="userDetailsService" ref="dummyUserDetailsService" />
</beans:bean>
<beans:bean class="org.springframework.security.extensions.kerberos.GlobalSunJaasKerberosConfig">
<beans:property name="debug" value="true" />
<beans:property name="krbConfLocation" value="/etc/krb5.conf" />
</beans:bean>
<beans:bean id="dummyUserDetailsService" class="main.server.DummyUserDetailsService"/>
</beans:beans>
so my DummyUserDetailsService.loadUserByUsername(Styring username) is invoked each time a secure page is requested, I am loading the user roles from database and don't want to run the query each time a request is made, is there any configuration I need to do to prevent this?
thanks Michael, I got it working by extending SpnegoAuthenticationProcessingFilter class and overriding doFilter
public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain)
throws IOException, ServletException {
HttpServletRequest request = (HttpServletRequest) req;
HttpServletResponse response = (HttpServletResponse) res;
if (skipIfAlreadyAuthenticated) {
Authentication existingAuth = SecurityContextHolder.getContext().getAuthentication();
if (existingAuth != null && existingAuth.isAuthenticated()
&& (existingAuth instanceof AnonymousAuthenticationToken) == false) {
chain.doFilter(request, response);
return;
}
}
super.doFilter(req, res, chain);
}
Tell Spring Security to cache the authentication in the HTTP Session. Here is how.