Spring security url pattern matching - spring

Edit / Delete
What should be pattern for above URL.I am using following but its not working
<intercept-url pattern="/index*" access="permitAll" />
<intercept-url pattern="/register*" access="permitAll" />
<intercept-url pattern="/welcome*" access="hasRole('Techincian')" />
<intercept-url pattern="/my/*" access="hasRole('Techincian')" />
<intercept-url pattern="/my/*\?param=value" access="hasRole('Techincian')" />

<intercept-url pattern="/my/**" access="hasRole('Techincian')" />
should work, but notice that this will match something that is <root of the project>/my/something . The above links are relative and may result in some other url will be not mached. To ensure you start from the root you can use c:url if you are in jsp.

Spring Form .I want to update the request made by customer by changing its status.some of field coming form controller .I want to submit form to controller in order to acess the values
h2>Update Request</h2>
>form:form method="POST" action="/my/update.htm" commandName="servicehistory">
table align="center" border="0">
<tr><td>Request Id: </td>
<td><form:input path="sr.ServiceRequestId" value="${sr.serviceRequestId}"></form:input> < other fields..............
<tr><td><input type="submit" value="Save" /></td></tr>
Controller which access the form value and update the request in database.but it is not happening.GUI displays resource is not available.It was working without Spring Security.
#RequestMapping(value="/my/update.htm",method=RequestMethod.POST)
public ModelAndView update(#ModelAttribute("servicehistory") #Valid ServiceHistories sh1,BindingResult result,ModelMap map)
{
Redirect it to another page after validating the form
return new ModelAndView(("redirect:/displaylist.htm"));
}
>Spring Security which implement security after matching url and user role
< http auto-config="true" use-expressions="true">
<intercept-url pattern="/admin/*" access="hasRole('Technician')" />
<intercept-url pattern="/my/**" access="hasRole('Techincian')" />

This is JSp page that is used to assign the compalint to techincian. After hitting submit, it give number format exceptions.
<c:forEach items="${hlist}" var="history" varStatus="i">
<tr>
<td><form:input path="requests[${i.index}].ServiceRequestId" value="${history.serviceRequestId }"></form:input></td>
<td><form:input path="requests[${i.index}].Description" value="${history.description }"></form:input></td>
<td><form:select multiple="false" path="requests[${i.index}].userto.UserId">
<form:option value="NONE" label="--- Select ---" />
<c:forEach items="${user}" var="u" varStatus="index">
<form:option label="${u.userName}" value="${u.userId}" />
</c:forEach>
</form:select>
</tr>
</c:forEach>
<tr><td> <input type="submit" value="Assign Technicians"></td></tr>
>Controller : I am using Autopopulating list to access list coming from above form.But it gives Number format exception. But it is working for another scenario which is identical to this one.
#ModelAttribute("requestForm")
public RequestForm getRequest()
{
RequestForm rf=new RequestForm();
rf.setRequests(new AutoPopulatingList(ServiceRequests.class));
return rf;
}
#RequestMapping(value="/admin/assigntech.htm",method=RequestMethod.POST)
public String assign(#ModelAttribute("requestForm") RequestForm requestForm,BindingResult result,ModelMap map)
{
List<ServiceRequests> sr=(List<ServiceRequests>)requestForm.getRequests();
System.out.println(sr.size());
System.out.println(sr.get(0).getUserto().getUserId());
return "Welcome";
}

To match everything under a folder like /my/, you should use double star ** because the pattern matching follows Ant standard.

Related

Spring 4 mvc login intercepting

I am new at Spring mvc. I am working on a webpage on which users will be able to log in after they have registered and activated themselves.
I sucessfully implemented the Login part, it works fine.
I would like to check if the user has already activated his/her accout via email before the login process launches. Is it possible?
I have tried to solve it with a Login interceptor, but it seems the default "/j_spring_security_check" can not be intercepted. Except this link the interceptor works with all of the url-s.
Is it possible to intercept this default link?
My spring-security.xml
...
<http use-expressions="true">
<intercept-url pattern="/admin**" access="hasRole('ADMIN')" />
<access-denied-handler error-page="/403" />
<form-login login-page="/login"
authentication-failure-url="/login?error"
username-parameter="username"
password-parameter="password"/>
<logout logout-success-url="/login?logout" />
<!--enable csrf protection-->
<csrf />
</http>
<authentication-manager>
<authentication-provider user-service-ref="loginService" />
</authentication-manager>
LoginService
#Service("loginService")
public class LoginServiceImpl implements UserDetailsService {
//It is a regular UserDetailsService nothing extra stuff and works fine
...
}
Login.jsp
....
<div id="login-box">
<span style="color: red">${message}</span>
<c:url value="/j_spring_security_check" var="loginUrl"/>
<form name='f' action="${loginUrl}" method="post">
<p>
<label for="username">Email</label>
<input type="text" id="username" name="username"/>
</p>
<p>
<label for="password">Password</label>
<input type="password" id="password" name="password"/>
</p>
<input type="hidden"
name="${_csrf.parameterName}"
value="${_csrf.token}"/>
<button type="submit" class="btn">Log in</button>
</form>
</div>
...
mvc-dispatcher-servlet.xml
...
<mvc:interceptors>
<mvc:interceptor>
<mvc:mapping path="/j_spring_security_check"/>
<bean id="logininterceptor" class="org.psi.controller.LoginInterCeptor"></bean>
</mvc:interceptor>
</mvc:interceptors>
...
LoginInterceptor
public class LoginInterCeptor extends HandlerInterceptorAdapter {
#Override
public boolean preHandle(HttpServletRequest request,
HttpServletResponse response, Object handler) throws Exception {
//Do some check
System.out.println("some check");
return true;
}
}
Any other possible solution are welcome.
I would accomplish this by using either the locked or enabled property on the UserDetails object and let Spring handle the rest rather than trying to intercept the request. When the user confirms their email via the link you send them, flip the flag in the database to indicate the the user is either enabled or not locked.
Alternatively, if you really want to go the intercept route, what I might do is have the login form point to something other than j_spring_security_check, intercept whatever that is, and then (if desired) forward the request to j_spring_security_check. I'm not sure if you can actually override that url.

Spring security repeated redirects

I am using spring security in my application. I want the user to be logged in first before accessing any pages on the server, hence i am taking the redirect approach. But the redirect seems to be in an infinite loop cause it redirects me to the login page no matter how many times i submit the page. I tried debugging and the request always hits the GET instead of the POST method as i expected. I am using LDAP authentication using the details entered by the user on the form. Here is the code in the security context xml . Can someone point me in the right direction.
<http pattern="/resources/**" security="none" />
<http auto-config="true">
<intercept-url pattern="/login*" access="IS_AUTHENTICATED_ANONYMOUSLY" />
<intercept-url pattern="/**" access="ROLE_USER" />
<form-login login-page="/login" default-target-url="/dashboard"
authentication-failure-url="/loginfailed" />
</http>
<authentication-manager>
<authentication-provider>
<user-service>
<user name="jimi" password="jimispassword" authorities="ROLE_USER, ROLE_ADMIN" />
<user name="bob" password="bobspassword" authorities="ROLE_USER" />
</user-service>
</authentication-provider>
</authentication-manager>
When i remove the
<form-login login-page="/login" default-target-url="/dashboard"
authentication-failure-url="/loginfailed" />
it defaults to spring login page and it works but i have to use the user credentials from the configuration xml as opposed to LDAP credentials.
Edit**
<%# page language="java" contentType="text/html; charset=ISO-8859-1"
pageEncoding="ISO-8859-1"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<%#taglib uri="http://www.springframework.org/tags/form" prefix="form"%>
<%# taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
<c:set var="contextPath" value="${pageContext.request.contextPath}" />
<link rel="stylesheet" href="${contextPath}/resources/css/styles.css" type="text/css">
<h2 style="text-align:center">Login to continue to Application</h2>
<div align="center" class="div">
<form:form method="POST" modelAttribute="login" action="authenticate">
<table>
<tr>
<td><form:label path="username" class="label">Username:</form:label></td>
<td><form:input path="username" class="input"/></td>
<td><form:errors path="username" class="error" /></td>
</tr>
<tr>
<td><form:label path="password" class="label">Password:</form:label></td>
<td><form:password path="password" class="input"/></td>
<td><form:errors path="password" class="error"/></td>
</tr>
<tr>
<td colspan="2" align="right"><input type="submit"
value="Login" class="button"/></td>
</tr>
</table>
</form:form>
</div>
thanks
Sree
#sri
as mentioned in your code i can see that you have intercepted the URL "/login*"
now any url with login at the end will be intercepted by spring security and after that you have to put the correct credentials....
now After giving credentials your are redirected to page /login
now its clear that again our url is ending with login hence it is intercepted again by spring security ...
thats why the loop continues....
Possible Solution
this may work for you,
just put the following code below <http pattern="/resources/**" security="none" /> tag as shown:
code:
<http pattern="/resources/**" security="none" />
<http pattern="/Login.html" security="none" />
Ok. Finally i got to a working state. Here are the changes i made to the security context xml
<intercept-url pattern="/login/**" access="IS_AUTHENTICATED_ANONYMOUSLY"/>
the url regex change. And also the action in my login.jsp is now
action="/login/authenticate"
and finally the controller request mapping path is updated.
Hope this helps anyone who has a similar issue. I am yet to discover if this is the right approach to achieve it but works for now.
-Sree

Spring security 3.1.4 backdoor

I have this problem:
in a java web-app (with spring and spring-security 3.1.4) there's a sso authentication; this means the user authenticates as soon as he log in on his pc.
The configuration is this:
<sec:http>
<sec:logout />
<sec:form-login login-page="/login.jsp" default-target-url="/" />
<sec:anonymous username="guest" granted-authority="ROLE_GUEST" />
<sec:custom-filter ref="headersFilter" after="SECURITY_CONTEXT_FILTER" />
<sec:custom-filter ref="jaasFilter" after="SERVLET_API_SUPPORT_FILTER" />
</sec:http>
and this works (actually login.jsp doesn't exist because the user is already logged in as I said above).
Now the problem is that I want to have a "backdoor";this means there should be a login page for me and my team to test and mantain the app.
It should work like this:
-I call localhost/wepapp/myloginpage and I should see the myloginpage.jsp (this works now);
-I click on "login" button and I enter in the second " element" and if the login is ok then I should get redirected to "/" (this doesn't work and I'm simply redirected on "login");
-with the configuration below it seems that I can see "/" without authentication, too, if I call it (localhost/wepapp)
I tried this configuration but it doesn't work, I mean I can see "/" without authentication and I get redirected to login (I also tried other small variations but same result, more or less):
<sec:http pattern="/myloginpage">
<sec:logout />
<sec:form-login login-page="/myloginpage" default-target-url="/" />
</sec:http>
<sec:http pattern="/login">
<sec:logout />
<sec:form-login login-page="/login" default-target-url="/" />
<sec:anonymous username="guest" granted-authority="ROLE_GUEST" />
<sec:custom-filter ref="headersFilter" after="SECURITY_CONTEXT_FILTER" />
<sec:custom-filter ref="jaasFilter" after="SERVLET_API_SUPPORT_FILTER" />
</sec:http>
My myloginpage.jsp:
<form action="login" method="POST">
<table>
<tr>
<td>
Name
</td>
<td>
<input type="text" name="name">
</td>
</tr>
.........
</form>
I also have the controller for myloginpage:
#Controller
public class Myloginpage {
publicMyloginpage() {
}
#RequestMapping("/myloginpage")
public String home() {
return "myloginpage";
}
}
Thankx,
Adrian
It seems you are missing the <intercept-url> tags to configure access to certain paths.
<sec:intercept-url pattern="/login*" access="IS_AUTHENTICATED_ANONYMOUSLY" />
<sec:intercept-url pattern="/secure/**" access="ROLE_USER" />

Security Session in spring. Stay logged in

I'm currently trying to implement an login-mechanism to my spring web application and I'm a little bit confused about the security concepts which are used in spring.
If I access a page requiring login, it is correctly redirecing to the login page. After login the actual page is visible (good so far).
Code for this
<security:http use-expressions="true" auto-config="true">
<security:intercept-url pattern="/login" access="permitAll" />
<security:intercept-url pattern="/**" access="hasRole('ROLE_USER')" />
<security:form-login login-page="/login" default-target-url="/welcome"
authentication-failure-url="/loginfailed" />
<security:logout logout-success-url="/logout" />
<security:remember-me/>
</security:http>
However, if I access the same page again I need to login AGAIN. So I need some kind of security-session. I already tried and read lots of things about remember-me and session-management but couldn't find out how to do it.
Can somebody please give me some directions, the appropriate chapter in the spring documentation or a keyword?
Login Form
<form name='f' action="<c:url value='j_spring_security_check' />"
method='POST'>
<table>
<tr>
<td>User:</td>
<td><input type='text' name='j_username' value=''>
</td>
</tr>
<tr>
<td>Password:</td>
<td><input type='password' name='j_password' />
</td>
</tr>
<tr>
<td colspan='2'><input name="submit" type="submit"
value="submit" />
</td>
</tr>
<tr>
<td colspan='2'><input name="reset" type="reset" />
</td>
</tr>
</table>
</form>
LoginController.java
#RequestMapping(value="/login", method = RequestMethod.GET)
public String login(ModelMap model) {
return "login";
}
#RequestMapping(value="/loginfailed", method = RequestMethod.GET)
public String loginerror(ModelMap model) {
model.addAttribute("error", "true");
return "login";
}
#RequestMapping(value="/logout", method = RequestMethod.GET)
public String logout(ModelMap model) {
return "login";
}
You'll need to this to your security definition in conf file:
<security:remember-me services-alias="rememberMeService" data-source-ref="dataSource" user-service-ref="userService"/>
</security:http>
and create a persistnet logins table
create table persistent_logins (username varchar(64) not null, series varchar(64) primary key, token varchar(64) not null, last_used timestamp not null)
But I am now repeating the Official docs
It's quite mysterious why the security session is not maintained for the second request after the login, because your config looks fine. Some logs would be useful to troubleshoot this issue. Enable trace level logging on org.springframework.security and share the logs after reproducing the problem.
A comment would have been enough to say this so far, but I also wanted to clarify the configuration and usage of the remember-me feature, because you had some problem there too.
The remember-me service should work with the simple configuration that you have in your original question. As you didn't specify a data-source-ref on <remember-me>, a simpler and less secure implementation will be applied which doesn't persist the tokens that were issued to the client.
It's not mandatory, but by configuring the data-source-ref you could gain some additional security: you would be able to warn the user if his remember-me token (cookie) had been stolen and used by an attacker to log in to your site with the user's identity. This is worthwhile enough to consider investing the additional effort.
Now the important thing: an under-documented feature of the remember-me service is that the client has to explicitly ask the server to remember his login by sending a request parameter with the name _spring_security_remember_me. So you'll have to insert something like the following snippet into your login form.
<p>
<label for="_spring_security_remember_me">Remember-me</label>
<input id="_spring_security_remember_me"
name="_spring_security_remember_me" type="checkbox"/>
</p>
The remember-me service won't do anything without this. (For the sake of completeness: there is an alternative option to set the alwaysRemember flag on the remember-me service, but that's a bit inconvenient, because this configuration point isn't exposed by the security namespace)

j_username cannot be accessed using spring_security_check

I created a login page using spring_security_check.
Here:
<form name='f' action="/sec_test/j_spring_security_check" method='POST'>
<table>
<tr>
<td>User:</td>
<td><input type="text" name="j_username" value=''>
</td>
</tr>
<tr>
<td>Password:</td>
<td><input type="password" name="j_password" />
</td>
</tr>
<tr>
<td colspan='2'><input name="submit" type="submit"
value="submit" />
</td>
</tr>
<tr>
<td colspan='2'><input name="reset" type="reset" />
</td>
</tr>
</table>
</form>
But I can not have access to j_username afterward.
I've tried:
* request.getParameter("j_username")
* request.getAttribute("j_username")
* request.getAttribute("j_username")
* request.getUserPrincipal().getName()
* request.getRemoteUser()
From all of them, all I'm getting is null!
Any idea what to do?
Spring does authentication for you based on type of the authentication configured in your configuration file. Once authentication is successful it redirects to the login success url(say /login.htm). Because it redirects to /login.htm, you will not get any request parameter (username/user role) unless explicitly set in request in overriden authentication filter.
After successful authentication spring stores the authenticated information in security context, including user roles. You can access this information from SecurityContext. Refer - link
I'd be interested to see your spring config files. Regardless, it appears you are trying to validate the user's credentials when spring security will actually do that for you. If you're unsure how to get started, read up on spring's documentation, including any online tutorials you can find. Here's what my spring security config looks like:
<security:http auto-config="true" use-expressions="true" access-denied-page="/login.html">
<security:form-login
login-page="/login.html"
authentication-failure-url="/loginfail.html"
default-target-url="/authenticate.html"/>
<security:logout
invalidate-session="true"
logout-success-url="/login.html"
logout-url="/logoff.html"/>
</security:http>
<bean id="securityDataSource" class="org.springframework.jndi.JndiObjectFactoryBean">
<property name="jndiName" value="java:comp/env/security_DS"/>
<property name="resourceRef" value="true"/>
</bean>
<bean id="encoder" class="org.springframework.security.crypto.password.StandardPasswordEncoder" />
<security:authentication-manager>
<security:authentication-provider>
<security:password-encoder ref="encoder" />
<security:jdbc-user-service
data-source-ref="securityDataSource"
authorities-by-username-query="SELECT l.user_name as username, r.role_name AS authority FROM login l join user_role ur on l.user_id = ur.user_id join role r on ur.role_id = r.role_id WHERE l.user_name = ?"
users-by-username-query="SELECT user_name as username, password_value AS password, active_flg AS enabled FROM login WHERE user_name = ?"
/>
</security:authentication-provider>
</security:authentication-manager>
If you want to have access to the user name after spring has validated the user's credentials, do something like this:
#RequestMapping(value = { "/authenticate.html" }, method = { RequestMethod.GET, RequestMethod.HEAD })
public ModelAndView authenticateUser(final HttpServletRequest httpServletRequest, HttpSession httpSession, Authentication authentication) {
User user = (User) authentication.getPrincipal();
String userName = user.getUsername();
...
You can see that the request will be forwarded to the /authenticate.html method based on the default-target-url that I specified in my spring config.

Resources