Spring security 3.1.4 backdoor - spring

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" />

Related

Spring Security (3.0.5), different behavior in production (SSL) - ( ERR_TOO_MANY_REDIRECTS)

My Spring-login has been working from day 1 (since 2013) , it now only works on my local machine (localhost:8080) but not on the production-site (https). So the only thing that has been changed is that I have a new domain (https://naturforskaren.se/) instead of (https://dina-web.net/naturalist)
in production I either get his error (chrome) https://<url-to-site>/loginsuccess:
This page isn’t working <url-to-site> redirected you too many times.
Try clearing your cookies.
ERR_TOO_MANY_REDIRECTS
or I get this error (firefox) https://<url-to-site>/loginsuccess:
The page isn’t redirecting properly
An error occurred during a connection to https://<url-to-site>/loginsuccess
This problem can sometimes be caused by disabling or refusing to accept cookies.
on Internet Explorer I get the following: https://<url-to-site>/loginsuccesss
make sure you've got the right web address: <url-to-site>
THis is my code:
(0) this is a part of the spring-security.xml file:
<security:http auto-config="true" disable-url-rewriting="true" use-expressions="true" access-denied-page="/denied" >
<!--<intercept-url pattern="/secure/**" access="ROLE_USER" requires-channel="https"/>-->
<security:intercept-url pattern="/login" access="permitAll" />
<security:intercept-url pattern="/admin/**" access="hasRole('ROLE_ADMIN')" requires-channel="https" />
<security:intercept-url pattern="/loginsuccess" access="hasRole('ROLE_USER')" requires-channel="https" />
<security:intercept-url pattern="/logout" access="permitAll" requires-channel="http" />
<security:form-login
login-page="/login"
authentication-failure-url="/login?error=true"
default-target-url="/loginsuccess"/>
<security:logout
invalidate-session="true"
logout-success-url="/logut"
logout-url="/logut"/>
</security:http>
(1) The form (login.jps)
<form name='my_form' action="<c:url value='j_spring_security_check' />" method='POST'>
<div class="form-group">
<label for="j_username"><fmt:message key="login.username" /></label>
<input style="margin-bottom: 10px" type='text' name='j_username' value='' class="form-control" placeholder="<fmt:message key="login.username_message" />" />
<label for="j_password"><fmt:message key="login.password" /></label>
<input type='password' class="form-control" name='j_password' placeholder="<fmt:message key="login.password_message" />" />
</div>
<button type="submit" class="btn btn-primary"><fmt:message key="submit" /></button>
</form>
A selection from the LoginFormController looks like this
#RequestMapping(value = "/loginsuccess", method = RequestMethod.GET)
public String loginSuccess(ModelMap model, Principal principal) throws Exception {
String redirectTo = "redirect:/";
HttpSession session = super.getSession();
Map<String, Object> searchMap = new HashMap<>();
searchMap.put("username", principal.getName());
User user = (User) genericService.findByNamedQuery("User.findByUsername", searchMap);
if (user == null) {
String prefixError = "user not found in database ";
logger.info(prefixError);
session.setAttribute("exception", prefixError);
redirectTo = redirectTo.concat("error/");
// return redirectTo;
} else {
session.setAttribute("loginUser", user);
final String preferredLanguage = user.getPreferredLanguage();
session.setAttribute("lang", preferredLanguage);
setUser(user);
logger.info("Admin-Login: success : " + getUser().getUsername() + " (lang : " + preferredLanguage + ")");
Taxon taxon = (Taxon) session.getAttribute("currentTaxon");
if (taxon != null) {
redirectTo = redirectTo.concat("species/" + taxon.getUuid());
}
}
So in production: I get the /loginsuccess
I do get the log in genericService from this statement :
User user = (User) genericService.findByNamedQuery("User.findByUsername", searchMap);
so the user is correct and the login is ok.
I am not getting the the log from this statement
logger.info("Admin-Login: success : " + getUser().getUsername() + " (lang : " + preferredLanguage + ")");
So, why am I now running into this error?
I have not changed any Spring versions , it is and has always been the following:
<spring.version>3.1.2.RELEASE</spring.version>
<springsecurity.version>3.0.5.RELEASE</springsecurity.version>
best, i
The answer was in the spring-security.xml-file:
change from 'https' to 'http'
Before:
<security:intercept-url pattern="/login" access="permitAll" />
<security:intercept-url pattern="/admin/**" access="hasRole('ROLE_ADMIN')" requires-channel="https" />
<security:intercept-url pattern="/loginsuccess" access="hasRole('ROLE_USER')" requires-channel="https" />
and after:
<security:intercept-url pattern="/login" access="permitAll" />
<security:intercept-url pattern="/admin/**" access="hasRole('ROLE_ADMIN')" requires-channel="http" />
<security:intercept-url pattern="/loginsuccess" access="hasRole('ROLE_USER')" requires-channel="http" />

Failed to evaluate expression with spring security

I have a Spring rest service, and I'm trying to add security to it. I followed this tutorial, but when I try to access the service directly I get the following error:
There was an unexpected error (type=Internal Server Error,
status=500). Failed to evaluate expression 'ROLE_USER'
Here's my security configuration:
webSecurityConfig.xml
<http entry-point-ref="restAuthenticationEntryPoint">
<intercept-url pattern="/**" access="ROLE_USER"/>
<form-login
authentication-success-handler-ref="mySuccessHandler"
authentication-failure-handler-ref="myFailureHandler"
/>
<logout />
</http>
<beans:bean id="mySuccessHandler"
class="com.eficid.cloud.security.rest.AuthenticationSuccessHandler"/>
<beans:bean id="myFailureHandler" class=
"org.springframework.security.web.authentication.SimpleUrlAuthenticationFailureHandler"/>
<authentication-manager>
<authentication-provider>
<user-service>
<user name="temp" password="temp" authorities="ROLE_USER" />
</user-service>
</authentication-provider>
</authentication-manager>
SpringSecurityConfig:
public class SpringSecurityConfig {
public SpringSecurityConfig() {
super();
}
}
I'm also getting this error when trying to use curl to log in:
{
"timestamp":1460399841286,
"status":403,"error":"Forbidden",
"message":"Could not verify the provided CSRF token because your session was not found.",
"path":"/spring-security-rest/login"
}
Do I need to add the csrf token manually to the command? The service has a self-signed certificate, if that makes any difference.
If you don't need CRF to be enabled, then you can disable it in webSecurityConfig.xml file like below:
<http auto-config="true" use-expressions="true">
<intercept-url pattern="/login.html" access="hasRole('ANONYMOUS')" />
<intercept-url pattern="/**" access="hasRole('ROLE_USER')"/>
<!-- This form is a default form that used to login
<http-basic/>
-->
<form-login login-page="/login.html"/>
<csrf disabled="true"/>
</http>
If CSRF is enabled, you have to include a _csrf.token in the page you want to login or logout.The below code needs to be added to the form:
<input type="hidden" name="${_csrf.parameterName}"
value="${_csrf.token}" />
You need hasRole('ROLE_USER') in the intercept-url element.
<intercept-url pattern="/**" access="hasRole('ROLE_USER')"/>
See the docs for the other expressions, that you can use.
Spring security blocks POST requests.
To enable it you can either:
Add after all you forms requests :
<input type="hidden" name="${_csrf.parameterName}" value="${_csrf.token}" class="form-control" />
(For example:
<form id="computerForm" action="addComputer" method="POST">
<input type="hidden" name="${_csrf.parameterName}"
value="${_csrf.token}" class="form-control" />
)
Or if you use anotation, you can allow POST directly in your code by adding the csrf().disable on your WebSecurityConfigurerAdapter (I havent found the xml equivalent yet) :
#Override
protected void configure(HttpSecurity http) throws Exception {
http.authorizeRequests()
.antMatchers("/admin/**").access("hasRole('ROLE_ADMIN')")
.and().formLogin()
.csrf().disable()
;}

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

Call to j_spring_security_logout not working

I'm trying to setup the logut of my application with j_spring_security_logout but for some reason it's not working, I keep getting a 404 error.
I'm calling the function like this:
<img border="0" id="logout" src="./img/logout.png" />
I have in WebContent/jsp/ my application main page, and the login and logout pages are in WebContent/login/.
I've also checked this other post Problem with Spring security's logout but the solution given there is not working for me.
Here you can see my web.xml
<filter>
<filter-name>springSecurityFilterChain</filter-name>
<filter-class>
org.springframework.web.filter.DelegatingFilterProxy
</filter-class>
</filter>
<filter-mapping>
<filter-name>springSecurityFilterChain</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
And here my spring-security.xml
<http auto-config="true">
<intercept-url pattern="/*" access="ROLE_USER" />
<form-login login-page="/login/login.jsp"
authentication-failure-url="/login/errorLogin.jsp"/>
<logout logout-success-url="/" logout-url="/login/logout.jsp" />
</http>
<beans:bean id="myAuthenticationProvider"
class="myapp.web.authentication.WSAuthenticationProvider">
</beans:bean>
<authentication-manager>
<authentication-provider ref="myAuthenticationProvider"/>
</authentication-manager>
Thanks in advance.
the logout-url refers to a virtual URL, you need not have any resource by that name. You can do either this:
<logout logout-success-url="/" logout-url="/j_spring_security_logout" />
and the link on your page like this
<c:url value="/j_spring_security_logout" var="logoutUrl" />
Log Out
OR this:
<logout logout-success-url="/" logout-url="/logout" />
and the link as follows:
<c:url value="/logout" var="logoutUrl" />
Log Out
You were mixing both thats why you were getting 404 error.
check whether csrf is enabled. If csrf enabled, need to use post method to logout, add csrf token as hidden field. then use JavaScript to post the form to logout
With spring security 4 Logout has to be done through form button. CSRF token has to be submitted along. j_spring_security_logout does not work any longer. After spending one day i got following to be working.
Step 1: In your JSP page
<c:url var="logoutUrl" value="/logout"/>
<form action="${logoutUrl}" method="post">
<input type="submit" value="Logout"/>
<input type="hidden" name="${_csrf.parameterName}" value="${_csrf.token}"/>
</form>
Step 2
<security:http use-expressions="true">
<security:form-login login-page="/login" authentication-failure-url="/login?error=true" />
<security:logout logout-success-url="/login" invalidate-session="true" logout-url="/logout" />
</security:http>
Step 3 In your login controller
//Logout mapping
#RequestMapping("/logout")
public String showLoggedout(){
return "logout";
}
Step 4 You must have one logout.jsp
Important to see that it will land onto login page after logout.
<security:form-login login-page="/login" authentication-failure-url="/login?error=true" />
So this login page must be there with corresponding mappping to login.jsp or whatever to map in your controller.
also heres what your controller should look like
#RequestMapping("/logout")
public String logoutUrl(){
return "logout";
}
first set security-context.xml the following code...
<security:logout logout-success-url="/"
invalidate-session="true" />
then add this code to your jsp file..
<script>
function formSubmit() {
document.getElementById("logoutForm").submit();
}
</script>
<c:url var="logoutUrl" value="/logout" />
Logout
</li>
<form action="${logoutUrl}" method="post" id="logoutForm">
<input type="hidden" name="${_csrf.parameterName}" value="${_csrf.token}" />
</form>
In JAVA-BASED Spring MVC config, you have to configure it in your security config class:
#Override
protected void configure(HttpSecurity http) throws Exception {
super.configure(http);
http.servletApi().rolePrefix("");
http
.logout()
.logoutRequestMatcher(new AntPathRequestMatcher("/logout"));
}
This answer is doubled from, and is working on my case:
Spring Security Java Config not generating logout url

SSL only during login with spring security

I'm trying to use https only during login.
The problem is that when the application tries to switch from https to http I end up being redirected to the login form (as if the session is getting destroyed).
Here is the configuration I'm using:
<s:http auto-config="true" access-denied-page="/erro-403"
create-session="never">
<s:port-mappings>
<s:port-mapping http="8080" https="8443" />
</s:port-mappings>
<s:intercept-url pattern="/preferencias" access="IS_AUTHENTICATED_REMEMBERED"
requires-channel="http" />
<s:intercept-url pattern="/admin/**" access="ROLE_SIPAS_ADMIN"
requires-channel="http" />
<s:intercept-url pattern="/area-prestador/**"
access="ROLE_SIPAS_PRESTADOR, ROLE_SIPAS_ATENDENTE, ROLE_SIPAS_ADMIN"
requires-channel="http" />
<s:intercept-url pattern="/**"
access="IS_AUTHENTICATED_ANONYMOUSLY,IS_AUTHENTICATED_REMEMBERED"
requires-channel="https" />
<s:form-login login-page="/login" default-target-url="/"
authentication-failure-url="/login-error" always-use-default-target="false" />
<s:logout logout-url="/logout" logout-success-url="/" />
<s:remember-me />
</s:http>
<s:authentication-manager>
<s:authentication-provider user-service-ref="authenticationMBean">
<s:password-encoder hash="md5" base64="true" />
</s:authentication-provider>
</s:authentication-manager>
The only workaround that I've found is to check the remember-me option.
Any ideas of what am I doing wrong?
Although it's been a long time this question was posted and I am sure the author must have found a solution already, I am posting this answer for future reference.
This issue is discussed in Spring Security FAQs. A quick solution is to add this element to your s:http element:
<s:session-management session-fixation-protection="none"/>

Resources