I am developing a Spring MVC / Spring Security application.
I do not have any exceptions or errors, but there is a redirect loop on one of the pages.
I'm using Spring 3.0.1 and Spring Security 3.0.1.
My dispatcher-security.xml:
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:security="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
http://www.springframework.org/schema/security
http://www.springframework.org/schema/security/spring-security-3.0.xsd">
<security:http auto-config="true" use-expressions="true">
<security:form-login login-page="/login" default-target-url="/login" authentication-failure-url="/fail2login"/>
<security:logout logout-success-url="/"/>
<security:intercept-url pattern="/auth/**" access="hasRole('ANONYMOUS')" />
<security:intercept-url pattern="/js/**" access="hasRole('ANONYMOUS')" />
<security:intercept-url pattern="/css/**" access="hasRole('ANONYMOUS')" />
<security:intercept-url pattern="/**" access="hasRole('ADMIN')" />
</security:http>
<security:authentication-manager>
<security:authentication-provider>
<security:jdbc-user-service data-source-ref="dataSource1"
users-by-username-query=" select name,password,enabled from user where name=?"
authorities-by-username-query="select u.name, r.role from user u, role r where u.role = r.auto_id and u.name =? "
/>
</security:authentication-provider>
</security:authentication-manager>
</beans>
Please help me......
The default-target-url attribute defines the page where the user is redirected in case of a successful login. Usually it is the home page of your application. You have default-target-url="/login", so it redirects you back to the login page after a successful login.
I do not understand the meaning of the ANONYMOUS role in you example. If it is the build-in role for anonymous users, I think it is called ROLE_ANONYMOUS.
In this case you probably use it incorrectly, and these two lines:
<security:intercept-url pattern="/js/**" access="hasRole('ANONYMOUS')" />
<security:intercept-url pattern="/css/**" access="hasRole('ANONYMOUS')" />
should be replaced with something like this:
<security:intercept-url pattern="/js/**" access="hasRole('ROLE_ANONYMOUS') or hasRole('ROLE_USER')" />
<security:intercept-url pattern="/css/**" access="hasRole('ROLE_ANONYMOUS') or hasRole('ROLE_USER')" />
Otherwise unauthontificated users ONLY will be able to access the /js/ and /css/ directories.
ROLE_USER in not a build-in role, it is a role that you define manually for all authenticated users.
See also:
What is the difference between ROLE_USER and ROLE_ANONYMOUS
The Spring Security Reference: Anonymous Authentication
Related
My application can have below URLs:
/siteadmin/homepage/
/siteusers/customer/createCustomer
Below is my spring-security.xml:
<beans:beans>
<http auto-config="true">
<intercept-url pattern="/siteusers***" access="isAuthenticated()" />
<!-- <intercept-url pattern="siteusers/home/*" access="hasRole('USER') OR hasRole('ADMIN')" /> -->
<intercept-url pattern="/siteadmin***" access="hasRole('ROLE_ADMIN')" />`enter code here`
<form-login login-page="/siteusers/loginprocess/login" default-target-url="/siteusers/home/homepage"
login-processing-url="/siteusers/loginprocess/login"
authentication-failure-url="/siteusers/loginprocess/login?error" username-parameter="username"
password-parameter="password" />
<logout logout-success-url="/siteusers/loginprocess/login?logout" logout-url="/siteusers/loginprocess/logout" />
<!-- enable csrf protection -->
<csrf />
</http>
<authentication-manager>
<authentication-provider>
<user-service>
<user name="b" password="123456" authorities="ROLE_ADMIN" />
<user name="a" password="a" authorities="ROLE_USER" /><!-- This user can not access /admin url -->
</user-service>
</authentication-provider>
</authentication-manager>
</beans:beans>
If I logged in with user 'a' and hit URL http://localhost:8080/siteadmin/homepage/ it is allowing user 'a' to view the page although his role is not admin. But when I try to hit http://localhost:8080/siteadmin then Spring Security is working fine ie. its showing access denied page.
I want to restrict /admin/* URLs for users who doesn't have Admin role.
See AntPathMatcher:
The mapping matches URLs using the following rules:
? matches one character
* matches zero or more characters
** matches zero or more directories in a path
Some examples:
com/t?st.jsp - matches com/test.jsp but also com/tast.jsp or com/txst.jsp
com/*.jsp - matches all .jsp files in the com directory
com/**/test.jsp - matches all test.jsp files underneath the com path
org/springframework/**/*.jsp - matches all .jsp files underneath the org/springframework path
org/**/servlet/bla.jsp - matches org/springframework/servlet/bla.jsp but also org/springframework/testing/servlet/bla.jsp and org/servlet/bla.jsp
Your pattern /siteadmin***misses slashes. Use /siteadmin/**.
I am using Spring MVC and I am trying to make an html page accesible without the need to login. My security xml configuration is as follows:
<http auto-config="true" use-expressions="true">
<intercept-url pattern="/err404.html" access="permitAll()" />
<intercept-url pattern="/login.html" access="permitAll()"/>
<intercept-url pattern="/accesibleWithoutLogin.html" access="permitAll()" />
<intercept-url pattern="/assets/**" access="permitAll()" />
<intercept-url pattern="/**" access="hasRole('AUTH_ADMIN')" />
<form-login login-page="/login.html"
login-processing-url="/static/j_spring_security_check"
authentication-success-handler-ref="authSuccessHandler"
authentication-failure-url="/login.html?t=error" />
<access-denied-handler error-page="/403" />
<logout logout-success-url="/login.html?act=logout" />
</http>
with this configuration I can access accesibleWithoutLogin.html but all the back-end(ajax requests to spring mvc) functionality is lost.
How can this page be fully functinal without having to login?
I want to add the following prefix to all my urls
/login should now be /springmvc/login
What are the changes that needs to be made. I add the following but no use. I also tried a updating all of the following no luck, sometime the login page works but the result page which is mostly return "login" does not work
<bean class="org.springframework.web.servlet.mvc.support.ControllerClassNameHandlerMapping">
<property name="pathPrefix" value="springmvc" />
<property name="caseSensitive" value="false" />
</bean>
I have updated my controller as follows
#RequestMapping("/springmvc")
public class LoginController {
my web.xml is as follows, I havn't updated those
<servlet-mapping>
<servlet-name>mvc-dispatcher</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
<filter-mapping>
<filter-name>springSecurityFilterChain</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
my spring security related code is as follows
<http access-decision-manager-ref="accessDecisionManager" auto-config="true">
<intercept-url pattern="/welcome*" access="ADMIN" />
<form-login login-page="/login" default-target-url="/welcome"
authentication-failure-url="/loginfailed" />
<logout logout-success-url="/logout" />
</http>
I would start by adding '/springmvc' to the mapping for your dispatcher servlet.
<servlet-mapping>
<servlet-name>mvc-dispatcher</servlet-name>
<url-pattern>/springmvc/*</url-pattern>
</servlet-mapping>
That should give you a common prefix for your controllers. You may have to tweak spring security separately to get the login/logout links working. E.G.
<http access-decision-manager-ref="accessDecisionManager" auto-config="true">
<intercept-url pattern="/springmvc//welcome*" access="ADMIN" />
<form-login login-page="/springmvc/login" default-target-url="/springmvc/welcome"
authentication-failure-url="/springmvc/loginfailed" />
<logout logout-success-url="/springmvc/logout" />
</http>
The ControllerClassNameHandlerMapping class is for setting up "convention over configuration" mappings. In other words the path is derived from the class/package name which means you don't need the #RequestMapping annotation at all.
In my Spring Security I have an issue. When I access url's like /admin, /client or even /admin/addUser.jsp it returns me to a login page (as it necessary) but when I access the url like /addUser (which mapped to Spring MVC controller) it returns me a page in any case even if user is not authenticated. What configuration I need to add/remove/modify in order to Security performs everything well.
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:security="http://www.springframework.org/schema/security"
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.xsd">
<security:http auto-config="true" use-expressions="true"> <!--access-decision-manager-ref="accessDecisionManager"-->
<security:intercept-url pattern="/login" access="permitAll"/>
<security:intercept-url pattern="/admin*/**" access="hasRole('ROLE_ADMIN')"/>
<security:intercept-url pattern="/client*/**" access="hasRole('ROLE_USER')"/>
<security:form-login login-page="/login" default-target-url="/index" authentication-failure-url="/loginFail"
authentication-success-handler-ref="redirectRoleStrategy"/>
<security:logout logout-success-url="/logout" invalidate-session="true"/>
<security:access-denied-handler error-page="/403"/>
</security:http>
<bean id="daoAuthenticationProvider" class="org.springframework.security.authentication.dao.DaoAuthenticationProvider">
<property name="userDetailsService" ref="userDetailsService"/>
</bean>
<bean id="authenticationManager" class="org.springframework.security.authentication.ProviderManager">
<property name="providers">
<list>
<ref local="daoAuthenticationProvider"/>
</list>
</property>
</bean>
<security:authentication-manager>
<security:authentication-provider user-service-ref="userDetailsService"/>
</security:authentication-manager>
<bean id="redirectRoleStrategy" class="com.payment.system.util.RoleBasedAuthenticationSuccessHandler">
<property name="roleUrlMap">
<map>
<entry key="ROLE_ADMIN" value="/admin"/>
<entry key="ROLE_USER" value="/client"/>
</map>
</property>
</bean>
</beans>
P.S.: By the way, my IDEA strikes-through me a <property name="providers"> line reporting me that this property is deprecated. To what property I should replace this?
Thank you!
Just add
<security:intercept-url pattern="/**" access="isFullyAuthenticated()" />
after all yours intercept-url tags (I mean it must be the last one)
For PS question: as explained in javadoc just use use constructor injection (via constructor-arg tag).
When you will add the configuration suggested by Maksym it will solve your authentication problem. But it will NOT solve your authorization problem. A user with the role ROLE_USER will be able to access to /addUser.
Two solutions:
1) Move all URLs that should be accessed by admin under to /admin**. This solution may be complicated.
2) Replace configuration suggested my Maxim by the following configuration:
<security:intercept-url pattern="/**" access="hasRole('ROLE_ADMIN')" />
Please not that in this case the user with the role ROLE_USER will be able to access only to URLs /client*/**
Please tell me if you need any additional help.
Best regards,
Michael
P.S. I recommend to define all beans via namespace as explained here: http://static.springsource.org/spring-security/site/docs/3.0.x/reference/ns-config.html
It should eliminate warnings.
I have configured spring authentication as below and its not working as expected
<sec:http auto-config="true">
<!-- Restrict URLs based on role -->
<sec:intercept-url pattern="pages/login.jsp" access="IS_AUTHENTICATED_ANONYMOUSLY" />
<sec:intercept-url pattern="/css/style.css" access="IS_AUTHENTICATED_ANONYMOUSLY" />
<sec:intercept-url pattern="pages/**" access="ROLE_USER" />
<!-- Override default login and logout pages -->
<sec:form-login login-page="/login.jsp"
default-target-url="/pages/products.xhtml"
authentication-failure-url="/login.html?login_error=1" />
<sec:logout logout-url="/logout" logout-success-url="/login.jsp" />
</sec:http>
On server start up i have been redirected to login.jsp ,if i use login form i am redirected to products.xhtml so far fine but if i directly access products.xhtml , it just allowing me to access the product.xhtml(Even after closing the broser or even on server restart) instead of redirecting to login.jsp . Could anyone just me what i am missing exactly?
Thanks & Regards
Vijay
Your patterns and URLs aren't consistent. You have "/login.jsp" for the login page and "pages/login.jsp" in the intercept-url pattern.
Try using:
<http pattern="/css/**" security="none">
<http>
<intercept-url pattern="/login.jsp" access="IS_AUTHENTICATED_ANONYMOUSLY" />
<intercept-url pattern="/**" access="ROLE_USER" />
<form-login login-page="/login.jsp"
default-target-url="/pages/products.xhtml"
authentication-failure-url="/login.html?login_error=1" />
<logout logout-url="/logout" logout-success-url="/login.jsp" />
</http>
The debug log for a particular request will explain exactly why it is or isn't secured.
Make sure you do not have a Cookie or a valid session...