Spring security authenticating error - spring

I have an application which I have configured so I can use database to authenticate users.
Trying to login as either user or admin with the set up username and password gives this error:
HTTP Status 404 - /project/login_error.jsp
So I tried to see if my url were working manually by putting the links in the navigation bar, the admin page comes up when I use this link:
https://localhost:8443/project/admin
Some other page also come up when entered manually, others do not show but gives me the error page.
The home page on the other hand does not show at all when I use this:
https://localhost:8443/project/home
It does not give any error but just redirects back to the login page.
No error comes up in the stack trace except for the hibernate HQL.
The security config:
<global-method-security pre-post-annotations="enabled" />
<http pattern="/resources/css/**" security="none"/>
<http pattern="/login.jsp*" security="none"/>
<http auto-config="true" use-expressions="true" access-denied-page="/denied"
authentication-manager-ref="authManager">
<intercept-url pattern="/**" requires-channel="https" />
<intercept-url pattern="/index" access="permitAll" requires-
channel='https'/>
<intercept-url pattern="/login" access="permitAll" requires-
channel='https'/>
<intercept-url pattern='/home' access="hasRole('ROLE_USER')" requires-
channel='https'/>
<intercept-url pattern='/admin' access="hasRole('ROLE_ADMIN')" requires-
channel='https'/>
<form-login login-page='/login' login-processing-url='/j_spring_security_check'
always-use-default-target="true" default-target-url="/home" authentication-failure-
url="/login_error.jsp?error=true"/>
<logout invalidate-session="true" logout-success-url='/login' />
</http>
<authentication-manager id="authManager">
<authentication-provider user-service-ref="***UserDetailsService">
<password-encoder hash="md5"/>
</authentication-provider>
</authentication-manager>
<beans:bean id="**UserDetailsService" class="com.**.**.**.**UserDetailsService">
</beans:bean>
Controller
#Controller
public class ApplicationController {
#RequestMapping(value="/home", method = RequestMethod.GET)
public String home(ModelMap model) {
logger.info("Download and Upload Page {}.");
Date date = new Date();
DateFormat dateFormat = DateFormat.getDateInstance(DateFormat.FULL);
String formattedDate = dateFormat.format(date);
model.addAttribute("serverTime", formattedDate );
return "home";
}
#RequestMapping(value="/login", method = RequestMethod.GET)
public String login(ModelMap model) {
logger.info("This is the login page {}.");
return "login";
}
Jsp page
<c:url value="/j_spring_security_check" var="loginUrl"/>
<form action="${loginUrl}" method="post" >
<label for="j_username">Username</label>
<input id="j_username" name="j_username" type="text" />
<label for="j_password">Password</label>
<input id="j_password" name="j_password" type="password" />
<input type="submit"
value="Login"/>
</form>
The HQL that shows in the output
Hibernate: select login0_.person_id as person1_1_, login0_1_.manager_id as
manager4_1_, login0_1_.email as email1_, login0_1_.name as name1_, login0_.enabled
as enabled3_, login0_.password as password3_, login0_.user_id as user5_3_,
login0_.username as username3_ from users login0_ inner join person login0_1_ on
login0_.person_id=login0_1_.person_id where login0_.username=?
I don't really know what I'm missing in this implementation. And I would appreciate any pointers on what the problem is.
Edit - adding security filter
<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>
<dispatcher>REQUEST</dispatcher>
<dispatcher>FORWARD</dispatcher>
<dispatcher>INCLUDE</dispatcher>
<dispatcher>ERROR</dispatcher>
</filter-mapping>

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

configuring spring-security and spring-mvc

I'm trying to configure my spring-security project for first time but when I try to login I receive a message: "ERR_TOO_MANY_REDIRECTS". May be somewhere under the hood it redirects to admin again, but where?
here is my spring-security.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:beans="http://www.springframework.org/schema/beans"
xsi:schemaLocation="http://www.springframework.org/schema/security
http://www.springframework.org/schema/security/spring-security-4.0.xsd
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-4.1.xsd">
<http use-expressions="true" >
<csrf disabled="true"/>
<intercept-url pattern="/admin" access="hasRole('Admin')" />
<intercept-url pattern="/" access="permitAll" />
<intercept-url pattern="/logout" access="permitAll" />
<access-denied-handler error-page="/403" />
<form-login login-page='/login' login-processing-url="/login" authentication-failure-url="/login?error=true"
username-parameter="username" password-parameter="password" />
<logout logout-url="/logout" logout-success-url="/logoutSuccessful" delete-cookies="JSESSIONID" invalidate-session="true" />
</http>
<authentication-manager>
<authentication-provider>
<jdbc-user-service data-source-ref="myDataSource"
users-by-username-query= "select login, password, 'true' from employee where login=?"
authorities-by-username-query= "select login, role from employee where login =? " />
</authentication-provider>
</authentication-manager>
<beans:import resource="data-source-cfg.xml"/>
</beans:beans>
controller class:
#Controller
#RequestMapping("/")
public class HelloController {
#RequestMapping(method = RequestMethod.GET)
public String printWelcome(ModelMap model) {
return "login";
}
#RequestMapping(value="/admin", method = RequestMethod.GET)
public String showAdmin(ModelMap model) {
return "admin";
}
#RequestMapping(value="/login", method=RequestMethod.GET)
public String enter(#ModelAttribute("employee") Employee employee, ModelMap model){
return "redirect:/admin";
}
...
Table with user's login and role looks like:
Employee
|id|login |password |first_name|last_name|mobile_phone|role |
|1 |login1 |password1 |name1 |lname1 |phone1 |User |
|2 |login2 |password2 |name2 |lname2 |phone2 |Admin |
spring security version is 4.0.3.
This is my first experience with spring-mvc and spring-security so the question may be noobie. What is wrong?
The problem is you are simply redirecting to the admin page on the /login resource, which is where it will send people if they are not logged in. Since /admin requires a specific role, it will try to go to the login page if the user is not logged in which you have redirecting back to the admin page, thus creating a loop.
You want to return a view and not redirect back to the admin page.

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

Spring Security openid-login attribute-exchange only call once at first time

I have trouble in spring security 3.1.
I'm going to use spring security openid-login with gmail, and I want to get user information using attribute-exchange. but if I use it, it is always called when user log-in my website.
How can i call only once at user sign-in my website?
I managed sign-in at openIdAuthFailureHandler, and I want to get user information in this bean...please help me!
(I found security:remember-me, but it doesn't work..)
security.xml
<?xml version="1.0" encoding="UTF-8"?>
<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.1.xsd
http://www.springframework.org/schema/security
http://www.springframework.org/schema/security/spring-security-3.1.xsd">
<security:global-method-security
secured-annotations="enabled" proxy-target-class="true" />
<security:http auto-config="true" access-denied-page="/denied/accessDenied">
<security:intercept-url pattern="/admin/**"
access="ROLE_ADMIN" />
<security:intercept-url pattern="/reservation/**"
access="ROLE_USER, ROLE_ADMIN" />
<security:intercept-url pattern="/board/**"
access="ROLE_ADMIN, ROLE_USER" />
<security:openid-login login-page="/"
login-processing-url="/j_spring_openid_security_check.do"
authentication-success-handler-ref="customAuthenticationHandler"
authentication-failure-handler-ref="openIdAuthFailureHandler">
<security:attribute-exchange identifier-match="https://www.google.com/.*" >
<security:openid-attribute name="email" type="http://schema.openid.net/contact/email" required="true" />
<security:openid-attribute name="firstname" type="http://axschema.org/namePerson/first" required="true" />
</security:attribute-exchange>
</security:openid-login>
<security:logout logout-url="/j_spring_openid_security_logout.do"
logout-success-url="/" invalidate-session="true" />
<!-- <security:http-basic /> -->
</security:http>
<security:authentication-manager>
<security:authentication-provider>
<!-- <security:user-service properties="/WEB-INF/resources/users.xml"
/> -->
<security:password-encoder ref="passwordEncoder" />
<security:jdbc-user-service id="userDetailsService"
data-source-ref="dataSource"
users-by-username-query="SELECT id as id, passwd as passwd, 1 as enabled FROM user WHERE id=?"
authorities-by-username-query="SELECT id as id, power as authority FROM user WHERE id=?" />
<!-- <security:password-encoder hash="sha-256"></security:password-encoder> -->
</security:authentication-provider>
</security:authentication-manager>
<bean id="customTokenRepository" class="com.jinyoung.reservation.openid.CustomTokenRepository" />
<bean id="openIdAuthFailureHandler" class="com.jinyoung.reservation.openid.OpenIDAuthenticationFailureHandler"/>
<bean id="passwordEncoder" class="org.springframework.security.authentication.encoding.ShaPasswordEncoder" />
</beans>
OpenIDAuthenticationFailureHandler
public class OpenIDAuthenticationFailureHandler extends
SimpleUrlAuthenticationFailureHandler {
#Override
public void onAuthenticationFailure(HttpServletRequest request,
HttpServletResponse response, AuthenticationException exception)
throws IOException, ServletException {
if (exception instanceof UsernameNotFoundException && exception.getAuthentication() instanceof OpenIDAuthenticationToken && ((OpenIDAuthenticationToken) exception.getAuthentication()).getStatus().equals(OpenIDAuthenticationStatus.SUCCESS)) {
DefaultRedirectStrategy redirectStrategy = new DefaultRedirectStrategy();
request.getSession(true).setAttribute("USER_OPENID_CREDENTIAL", ((UsernameNotFoundException)exception).getExtraInformation());
OpenIDAuthenticationToken openIdAuth = (OpenIDAuthenticationToken)exception.getAuthentication();
request.getSession(true).setAttribute("USER_OPENID_CREDENTIAL_EXTRA", openIdAuth);
for(OpenIDAttribute attr : openIdAuth.getAttributes()) {
System.out.printf("AX Attribute: %s, Type: %s, Count: %d\n", attr.getName(), attr.getType(), attr.getCount());
for(String value : attr.getValues()) {
System.out.printf(" Value: %s\n", value);
}
}
redirectStrategy.sendRedirect(request, response, "/login/registrationOpenid");
// redirect to create account page
/*redirectStrategy.sendRedirect(request, response,
"/?fail=true");*/
} else {
super.onAuthenticationFailure(request, response, exception);
}
}
}
Ran in to a similar problem which I solved by having two different form targets (j_spring_openid_security_check_signup and j_spring_openid_security_check) for the signup/login page. One used when signing up and one when logging in. In spring-security.xml we use two different configs, one that asks for attributes and one that don't:
<!-- Configure attribute-exchange for signup -->
<!-- will only match /j_spring_openid_security_check_signup -->
<security:http auto-config="true" use-expressions="true" path-type="ant" pattern="/j_spring_openid_security_check_signup">
<security:openid-login
login-processing-url="/j_spring_openid_security_check_signup"
user-service-ref="userDetailsService"
authentication-failure-handler-ref="authenticationFailureHandler"
authentication-success-handler-ref="authenticationSuccessHandler">
<security:attribute-exchange identifier-match="https://www.google.com/.*" >
<security:openid-attribute name="email" type="http://schema.openid.net/contact/email" required="true" />
<security:openid-attribute name="firstname" type="http://axschema.org/namePerson/first" required="true" />
</security:attribute-exchange>
</security:openid-login>
</security:http>
<!-- Skip attribute-exchange at log-in -->
<!-- match everything else -->
<security:http auto-config="true" use-expressions="true" path-type="ant">
<security:openid-login
login-processing-url="/j_spring_openid_security_check"
user-service-ref="userDetailsService"
authentication-failure-handler-ref="authenticationFailureHandler"
authentication-success-handler-ref="authenticationSuccessHandler"
/>
</security:http>
Then in the authenticationSuccessHandler you will have access to attributes while signing in but not at log-in.
-------------------------------I solved!!!------------------------------------------
I modified spring-security-openid-3.1.1.RELEASE.jar, and I call attribute-change only once at user access my site first time. if one who want to know, give me e-mail kjy30532#gmail.com !

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

Resources