Debugging LDAP with shiro in Tomcat - debugging

I have a web service, and for that I want to authenticate users.
I'm trying to have a form based authentication with org.apache.shiro.realm.ldap.JndiLdapRealm as my realm.
But when I enter the credentials nothing happens but redirecting to login page again. And there's nothing get printed on the log.
My Question is how can I debug the shiro to figure out what is happening?
Edit:
Here is my shiro ini file
[main]
authc.loginUrl = /login.jsp
authc.successUrl = /index.jsp
ldapRealm = org.apache.shiro.realm.ldap.JndiLdapRealm
ldapRealm.userDnTemplate = sAMAccountName={0},DC=aaa,DC=bbb
ldapRealm.contextFactory.url = ldap://aaa.bbb.ccc:3268
ldapRealm.contextFactory.systemUsername = admin
ldapRealm.contextFactory.systemPassword= password
securityManager.realms = $ldapRealm
[urls]
/login.jsp = authc
/logout = logout
/** = authc
Edit 2: my login jsp
<form name="loginform" method="post">
plain
<label for="username">Username:</label>
<input type="text" id="username" name="username" />
<br/>
<label for="password">Password:</label>
<input type="password" id="password" name="password" />
<br/>
<label for="rememberMe">Remember me:</label>
<input type="checkbox" id="rememberMe" name="rememberMe" value="true" />
<br/>
<input type="submit" value="Login" />
</form>
my web.xml
<listener>
<listener-class>org.apache.shiro.web.env.EnvironmentLoaderListener</listener-class>
</listener>
<filter>
<filter-name>ShiroFilter</filter-name>
<filter-class>org.apache.shiro.web.servlet.ShiroFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>ShiroFilter</filter-name>
<url-pattern>/*</url-pattern>
<dispatcher>REQUEST</dispatcher>
<dispatcher>FORWARD</dispatcher>
<dispatcher>INCLUDE</dispatcher>
<dispatcher>ERROR</dispatcher>
</filter-mapping>

Related

j_spring_security_check returning 404 on Tomcat but works on Jetty

I have a basic Spring security setup with Form based login. When submitting my login action to j_spring_security_check it works on Jetty but fails with 404 code on Tomcat (7 & 8). I am using Spring 3.2.
So submitting to server:port/app/j_spring_security_check returns 404 response.
My security http setup looks like the following:
<security:http >
<security:form-login login-page="/login.jsp"
username-parameter="j_username"
password-parameter="j_password" />
<security:intercept-url pattern="/admin/**" access="ROLE_ADMIN"/>
<security:custom-filter position="PRE_AUTH_FILTER" ref="springAccessManagerAuthenticationFilter"/>
<security:intercept-url pattern="/j_spring_security_check" access="IS_AUTHENTICATED_ANONYMOUSLY"/>
<security:session-management></security:session-management>
<security:headers>
<security:cache-control/>
<security:xss-protection/>
<security:hsts/>
<security:frame-options/>
<security:content-type-options/>
</security:headers>
</security:http>
The login page looks like the following:
<%# include file="/WEB-INF/jsp/tags.jsp"%>
<%#page session="false" %>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<title>Login</title>
</head>
<body id="login">
<form method="POST" action="<c:url value='j_spring_security_check' />"
id="loginForm" autocomplete="off">
Username : <input id="username" type="text" size="15" maxlength="60" name="j_username"><br><br>
Password : <input id="password" type="password" size="15" maxlength="60" name="j_password"><br><br>
<input type="hidden" name="${_csrf.parameterName}" value="${_csrf.token}"/>
<input value="Login" type="submit" id="submit" name="_eventId_nextpage">
</form>
</body>
</html>
My web.xml has the SpringSecurityFilterChain:
<!-- Spring Security -->
<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>
I finally figured this out as being a typo in web.xml on the default filter.
I had:
<servlet-mapping>
<servlet-name>default</servlet-name>
<url-pattern>/logout</url-pattern>
<url-pattern>/j_security_check</url-pattern>
</servlet-mapping>
j_security_check should have been j_spring_security_check

j_security_check login.jsp is not working with WebSphere Liberty profile

I have my LDAP configuration in server.xml in Websphere Liberty profile as follows.
<ldapRegistry baseDN="dc=mydc,dc=myroot,dc=myorg" bindDN="cn=myname,OU=Users,OU=myou,DC=mydc,DC=myroot,DC=myorg" bindPassword="xxxx" host="mycompanyldap" id="ldap" ignoreCase="true" ldapType="Microsoft Active Directory" port="389" realm="LdapRegistry" sslEnabled="false">
<activedFilters groupMemberIdMap="memberof:member" />
<activedFilters groupMemberIdMap="memberOf:member" />
</ldapRegistry>
I have my login.jsp which has this call in it..
<form name="frmLogin" action="j_security_check" method="POST">
<table width="100%">
<tr>
<td align="center">
<table id="loginPanel">
<thead>
<th id="titleRow" colspan="2">Media Inquiries</th>
</thead>
<tbody>
<tr id="firstRow">
<td class="label">LAN ID:</td>
<td class="field"><input type="text" id="j_username" name="j_username" maxlength="20" style="width: 150;"></td>
</tr>
<tr>
<td class="label"> Password: </td>
<td class="field"><input type="password" id="j_password" name="j_password" maxlength="20" style="width: 150;"></td>
</tr>
<tr>
<td id="submitRow" colspan="2">
<input type="submit" id="btnSubmit" value="Logon" onclick="return submitPage()">
</td>
</tr>
</tbody>
</table>
</td>
</tr>
</table>
I have the following defined in my web.xml
<!-- ========== Begin Authentication ========== -->
<security-constraint>
<display-name>All Users Constraint</display-name>
<web-resource-collection>
<web-resource-name>Protected Pages</web-resource-name>
<url-pattern>*.htm</url-pattern>
<http-method>GET</http-method>
<http-method>POST</http-method>
</web-resource-collection>
<auth-constraint>
<description>All Users Authorization Constraint</description>
<role-name>All Users</role-name>
</auth-constraint>
</security-constraint>
<login-config>
<auth-method>FORM</auth-method>
<realm-name>LdapRegistry</realm-name>
<form-login-config>
<form-login-page>/login.jsp</form-login-page>
<form-error-page>/login.jsp?loginFailed=true</form-error-page>
</form-login-config>
</login-config>
<security-role>
<role-name>All Users</role-name>
</security-role>
<!-- ========== End Authentication ========== -->
<!-- Declare Spring Security filter -->
<!-- Add a DelegatingFilterProxy -->
<filter>
<filter-name>springSecurityFilterChain</filter-name>
<filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
</filter>
<!-- Add a springSecurityFilterChain mapping -->
<filter-mapping>
<filter-name>springSecurityFilterChain</filter-name>
<url-pattern>*.htm</url-pattern>
</filter-mapping>
When I do the login using the form login , nothing happens on the front end.
I check the logs and there is this message.
[2/9/16 11:42:27:593 CST] 00000054 com.ibm.ws.logging.internal.impl.IncidentImpl I FFDC1015I: An FFDC Incident has been created: "com.ibm.ws.security.registry.RegistryException: CWIML0515E: The user registry operation could not be completed. The CN=myname,OU=Users,OU=myou,DC=mydc,DC=myroot,DC=myorg entity is not in the scope of the defined realm. Specify an entity that is in the scope of the configured realm in the server.xml file. com.ibm.ws.security.authentication.jaas.modules.UsernameAndPasswordLoginModule 93" at ffdc_16.02.09_11.42.27.0.log
WebSphere documentation shows this.. which is the exact message I received but I am not clear as to what I need to do to fix my server.xml.
http://www-01.ibm.com/support/knowledgecenter/SSAW57_8.5.5/com.ibm.websphere.messages.doc/com.ibm.ws.wim.util.resources.WimUtilMessages.html
CWIML0515E: The user registry operation could not be completed. The {0} entity is not in the scope of the {1} realm. Specify an entity that is in the scope of the configured realm in the server.xml file.
**Explanation** The operation cannot be performed because the specified entity is not in the scope of the realm.
**Action** Ensure that the unique name of the entity is specified correctly. If a realm name is specified in the Context object of the input object, ensure that the name is spelt correctly.
Can someone please help as to what I need to do to have my LDAP work correctly with my login. What do I need to change in my server.xml ?
Thanks
Dhiren
Here is the solution.
This needs to be added to either the web application or ear.
Note the realm of the ldap should be the LdapRealm that you set.
<application-bnd>
<security-role name="All Users">
<special-subject id="group:LdapRegistry/cn=yourCN,OU=Users,OU=,DC=,DC=,DC=" type="ALL_AUTHENTICATED_USERS"/>
<special-subject id="user:LdapRegistry/cn=yourCN,OU=Users,OU=,DC=,DC=,DC=" type="ALL_AUTHENTICATED_USERS"/>
</security-role>
</application-bnd>
Once you set this up. the war and ear can communicate with LDAP

No mapping found for HTTP request with URI [/.../j_spring_security_check] in DispatcherServlet with name 'servlet-dispatcher'

Plop,
Spring version: 4.0.2.RELEASE
Spring Security Version: 4.0.2.RELEASE
DB PostgreSQL Version: 9.4-1202-jdbc42
I'm trying to acces to my home page with a secure connection using spring-security.
When I try to connect with login/password I've got this error:
WARNING: No mapping found for HTTP request with URI
[/web-client-smarteo/j_spring_security_check] in DispatcherServlet
with name 'servlet-dispatcher'
When I submit with log/pass it's get me to:
http://localhost:8080/web-client-smarteo/j_spring_security_check?username=alfacamp&password=alfacam&submit=&%24%7B_csrf.parameterName%7D=%24%7B_csrf.token%7D
And show
HTTP 404 The requested ressource is unvailable
Details of my sample:
UPDATE
web.xml
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>
/WEB-INF/dispatcher-servlet.xml
/WEB-INF/spring-security.xml
</param-value>
</context-param>
<!-- Spring 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>
</filter-mapping>
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<servlet>
<servlet-name>servlet-dispatcher</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>/WEB-INF/dispatcher-servlet.xml</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>servlet-dispatcher</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
dispatcher-servlet.xml
<mvc:annotation-driven />
<context:component-scan base-package="com.smarteo.laugustoni.*" />
[...]
<bean
class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix">
<value>/vues/</value>
</property>
<property name="suffix">
<value>.jsp</value>
</property>
</bean>
spring-security.xml
<http auto-config="true" use-expressions="true">
<intercept-url pattern="/welcome**" access="hasRole('CUSTOMER')" />
<!-- access denied page -->
<access-denied-handler error-page="/403" />
<form-login
login-page="/connection"
default-target-url="/welcome"
login-processing-url="/j_spring_security_check"
authentication-failure-url="/connection?error"
username-parameter="username"
password-parameter="password" />
<logout logout-success-url="/connection?logout" />
<!-- enable csrf protection -->
<csrf/>
</http>
<!-- Select users and user_roles from database -->
<authentication-manager>
<authentication-provider>
<jdbc-user-service data-source-ref="dataSource"
users-by-username-query=
"select usr_name,usr_password from smarteo_user where usr_name=?"
authorities-by-username-query=
"select usr_name, usr_role from smarteo_user where usr_name =? " />
</authentication-provider>
</authentication-manager>
ConnectionController.java
package com.smarteo.laugustoni.controller;
import org.springframework.security.authentication.AnonymousAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.core.userdetails.UserDetails;
import javax.validation.Valid;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.ModelMap;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.servlet.ModelAndView;
import com.smarteo.laugustoni.services.User.IServiceUser;
#Controller
public class ConnectionController {
#RequestMapping(value={"/", "/welcome**"}, method = RequestMethod.GET)
public String defaultPage(ModelMap pModel)
{
return "connection";
}
#RequestMapping(value="/connexion", method = RequestMethod.GET)
public ModelAndView connection(
#RequestParam(value="error", required = false) String error,
#RequestParam(value = "logout", required = false)String logout)
{
ModelAndView model = new ModelAndView();
if (error != null) {
model.addObject("error", "Invalid username and password!");
}
if (logout != null) {
model.addObject("msg", "You've been logged out successfully.");
}
model.setViewName("connection");
return model;
}
Thanks for helping.
EDIT 1
connection.jsp
<%#page language="java" contentType="text/html; charset=ISO-8859-1"
pageEncoding="ISO-8859-1"%>
<%#taglib uri="http://www.springframework.org/tags" prefix="spring"%>
<%#taglib uri="http://www.springframework.org/tags/form" prefix="form"%>
<%#taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%>
<%#page session="true"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<body>
<form name="loginForm" action="/j_spring_security_check">
<!-- TextBox Section -->
<div class="input-group visible">
<spring:message code="connection.label.account"/>
<input name="username" path="username" placeholder="Nom du compte" type="text" class="form-control" aria-describedby="basic-addon1"/>
<div class="alert alert-danger" role="alert"><form:errors path="username" cssclass="error"/></div>
</div><br />
<div class="input-group visible">
<spring:message code="connection.label.password"/>
<input name="password" path="password" placeholder="Mot de passe" type="password" class="form-control" aria-describedby="basic-addon1"/><br />
<div class="alert alert-danger" role="alert"><form:errors path="password" cssclass="error"/></div>
</div><br />
<!-- TextBoxSection -->
<!-- Button Section -->
<button name="submit" type="submit" class="btn btn-default visible">
<spring:message code="connection.button.label.connect"/>
</button><br />
<!-- Button Section -->
<input type="hidden" name="${_csrf.parameterName}" value="${_csrf.token}" />
</form>
</body>
EDIT 2:
I'm now using:
<form name="loginForm" action="<c:url value='/login' />" method="POST" >
I had also change my spring-security.xml:
<http auto-config="true" use-expressions="true">
<intercept-url pattern="/welcome**" access="hasRole('CUSTOMER')" />
<!-- access denied page -->
<access-denied-handler error-page="/403" />
<form-login
login-page="/login"
default-target-url="/welcome**"
authentication-failure-url="/login?error"
username-parameter="username"
password-parameter="password" />
<logout logout-success-url="/login?logout" />
<!-- enable csrf protection -->
<csrf/>
</http>
And my ConnectionController.java
#RequestMapping(value = "/welcome**", method = RequestMethod.GET)
public String defaultPage()
{
return "home";
}
#RequestMapping(value = "/login", method = RequestMethod.GET)
public ModelAndView login(
#RequestParam(value = "error", required = false) String error,
#RequestParam(value = "logout", required = false) String logout)
{
ModelAndView model = new ModelAndView();
if (error != null) {
model.addObject("error", "Invalid username and password!");
}
if (logout != null) {
model.addObject("msg", "You've been logged out successfully.");
}
model.setViewName("connection");
return model;
}
#RequestMapping(value = "/403", method = RequestMethod.GET)
public ModelAndView accesssDenied() {
ModelAndView model = new ModelAndView();
//check if user is login
Authentication auth = SecurityContextHolder.getContext().getAuthentication();
if (!(auth instanceof AnonymousAuthenticationToken)) {
UserDetails userDetail = (UserDetails) auth.getPrincipal();
model.addObject("username", userDetail.getUsername());
}
model.setViewName("403");
return model;
}
I'm now getting State HTTP 405 - Request method 'POST' not supported when I'm trying to login
My problem was due to spring security version.
Indeed for 4.x you have to put the csrf in your form action.
My sources modified with the solution:
connection.jsp
<form name="loginForm" action="<c:url value='/login?${_csrf.parameterName}=${_csrf.token} }' />" method="POST" >
<!-- TextBox Section -->
<div class="input-group visible">
<spring:message code="connection.label.account"/>
<input name="username" path="username" placeholder="Nom du compte" type="text" class="form-control" aria-describedby="basic-addon1"/>
<!--<div class="alert alert-danger" role="alert"><form:errors path="username" cssclass="error"/></div>-->
</div><br />
<div class="input-group visible">
<spring:message code="connection.label.password"/>
<input name="password" path="password" placeholder="Mot de passe" type="password" class="form-control" aria-describedby="basic-addon1"/><br />
<!--<div class="alert alert-danger" role="alert"><form:errors path="password" cssclass="error"/></div>-->
</div><br />
<!-- TextBoxSection -->
<!-- Button Section -->
<input name="submit" type="submit" class="btn btn-default visible" value=<spring:message code="connection.button.label.connect"/> />
<br />
<!-- Button Section -->
</form>
spring-security.xml:
<http auto-config="true" >
<intercept-url pattern="/welcome**" access="hasRole('CUSTOMER')" />
<form-login login-page="/login"
default-target-url="/welcome"
username-parameter="username"
password-parameter="password"
authentication-failure-url="/403" />
<!-- enable csrf protection -->
<csrf disabled="true"/>
</http>

Spring Logout not working and redirecting

I have the following JSF Page:
<h:form>
<input type="hidden" name="${_csrf.parameterName}" value="${_csrf.token}" />
<b:navBar brand="TEST" brandHref="#" inverse="true">
<p:lightBox styleClass="menucolored">
<p:commandLink id="logout"
type="button"
action="/j_spring_security_logout"
value="Log Out" ajax="false"
styleClass="menucolored"/>
</p:lightBox>
</b:navBar>
</h:form>
Spring Security xml:
<http use-expressions="true" auto-config="true">
<form-login login-page="/pages/Login.xhtml"
login-processing-url="/j_spring_security_check"
authentication-failure-url="/loginPage?error=1"
default-target-url="/pages/Home.xhtml"
always-use-default-target="true"
username-parameter="j_username"
password-parameter="j_password"/>
<!-- On logout success load the login page -->
<logout logout-success-url="/pages/Login.xhtml" />
<!-- enable csrf protection -->
<csrf />
</http>
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>
<dispatcher>FORWARD</dispatcher>
<dispatcher>REQUEST</dispatcher>
</filter-mapping>
I have tried replacing the command link with
<h:outputLink value="${request.contextPath}/j_spring_security_logout">logout</h:outputLink>
or
<h:outputLink value="${pageContext.request.contextPath}/j_spring_security_logout">logout</h:outputLink>
Still no luck. When I click the button nothing happens.
If CSRF enabled, you must logout with a POST method. You need to wrap it in a standard HTML form instead:
<form action="${request.contextPath}/j_spring_security_logout" method="post">
<input type="submit" value="Log out" />
<input type="hidden" name="${_csrf.parameterName}" value="${_csrf.token}"/>
</form>
For using a link instead of a button, you'll need to write some javascript in order to make the link submit the form. See this post.
I fixed it:
public String doLogout() throws ServletException, IOException {
System.out.println("In doLogout()");
ExternalContext context = FacesContext.getCurrentInstance().getExternalContext();
RequestDispatcher dispatcher = ((ServletRequest) context.getRequest())
.getRequestDispatcher("/logout");
dispatcher.forward((ServletRequest) context.getRequest(),
(ServletResponse) context.getResponse());
FacesContext.getCurrentInstance().responseComplete();
System.out.println("End doLogout()");
return null;
}
I had to use /logout instead of /j_spring_security_logout
You can use this javascript solution for Spring Security 4 + CSRF + JSF:
Logout
<form action="logout" id="logout" method="post">
<input type="hidden" name="${_csrf.parameterName}"
value="${_csrf.token}" />
</form>

The requested resource (/springHibernate) is not available

I am getting this error as i have mentioned in title. I am making a sample application which is on angularJs, spring and hibernate. my application is working with spring, hibernate and jsp page but when I am not able to do it with angularJs. Here is the html page
<div ng-controller="empController">
<form>
<label>FirstName</label>
<input type="text" name="Firstname" ng-model="emp.firstName"/>
<br/>
<label>LastName</label>
<input type="text" name="lastName" ng-model="emp.lastName"/>
<br/>
<label>Email</label>
<input type="text" name="email" ng-model="emp.email"/>
<br/>
<label>Phone</label>
<input type="text" name="phone" ng-model="emp.phone"/>
<br/>
<input type="hidden" ng-model="emp.id" />
<input type="button" value="Save" ng-click="saveEmp()" />
</form>
below is the code of angularJs controller
function empController($scope,$http,$location) {
$scope.saveEmp = function(emp) {
$http.post('add', $scope.emp).success(function() {
//location.href = "index.html";
});
$scope.emp = {};
};
}
Below is the code of springController
#RequestMapping(value = "/", method = RequestMethod.GET)
public String listEmployees(ModelMap map)
{
map.addAttribute("emp", new TestEmployee());
System.out.println("calling listEmployees");
return "editEmployeeNew";
}
#RequestMapping(value = "/add", method = RequestMethod.POST)
public String addEmployee(#ModelAttribute(value="emp") TestEmployee emp, BindingResult result)
{
employeeManager.addEmployee(emp);
return null;
}
Below is my web.xml file
<servlet>
<servlet-name>employee</servlet-name>
<servlet-class>
org.springframework.web.servlet.DispatcherServlet
</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>employee</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>/WEB-INF/employee-servlet.xml</param-value>
</context-param>
Below is my employee-servlet.xml (snippet)
<bean id="jspViewResolver"
class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="viewClass"
value="org.springframework.web.servlet.view.JstlView" />
<property name="prefix" value="/WEB-INF/view/" />
<property name="suffix" value=".html" />
</bean>
I have searched this problem on net but nothing helped me as i am using angularJs. Kindly help me. I am new to these technologies so kindly help me with code if I am doing something in wrong way.

Resources