Skip to content

Instantly share code, notes, and snippets.

@leonelag
Created October 4, 2012 12:23
Show Gist options
  • Save leonelag/3833258 to your computer and use it in GitHub Desktop.
Save leonelag/3833258 to your computer and use it in GitHub Desktop.
Advanced Spring Security. How to configure Spring beans to set up Spring Security without using the Spring Security namespace.
<%@page contentType="application/json; charset=UTF-8"%>{"status":"nauth","message":"Not authorized."}
import java.io.IOException;
import java.io.PrintWriter;
import javax.servlet.http.HttpServletResponse;
public class JsonHelper {
void sendJson(HttpServletResponse response, String status, Integer statusCode, String msg) throws IOException {
String jsonObject = "{"
+ "\"status\": \"" + status + "\","
+ "\"message\":\"" + msg + "\""
+ "}";
response.setContentType("application/json");
response.setCharacterEncoding("UTF-8");
response.setStatus(statusCode);
PrintWriter out = response.getWriter();
out.print(jsonObject);
out.flush();
out.close();
}
}
import static javax.servlet.http.HttpServletResponse.SC_UNAUTHORIZED;
import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.springframework.security.access.AccessDeniedException;
import org.springframework.security.web.access.AccessDeniedHandlerImpl;
public class MyAccessDeniedHandlerImpl extends AccessDeniedHandlerImpl {
private JsonHelper jsonHelper;
public void setJsonHelper(JsonHelper jsonHelper) {
this.jsonHelper = jsonHelper;
}
/**
* Return 'Unauthorized' as a Json message
*/
@Override
public void handle(
HttpServletRequest request,
HttpServletResponse response,
AccessDeniedException reason)
throws ServletException, IOException {
jsonHelper.sendJson(response, "nauth", SC_UNAUTHORIZED, "Unauthorized.");
}
}
import static javax.servlet.http.HttpServletResponse.SC_UNAUTHORIZED;
import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.springframework.beans.factory.annotation.Required;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.web.authentication.AuthenticationFailureHandler;
public class MyAuthenticationFailureHandler implements AuthenticationFailureHandler {
private JsonHelper jsonHelper;
@Required
public void setJsonHelper(JsonHelper jsonHelper) {
this.jsonHelper = jsonHelper;
}
@Override
public void onAuthenticationFailure(
HttpServletRequest request,
HttpServletResponse response,
AuthenticationException exception)
throws IOException, ServletException {
jsonHelper.sendJson(response, "nauth", SC_UNAUTHORIZED, "Unauthorized.");
}
}
import static javax.servlet.http.HttpServletResponse.SC_OK;
import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.beans.factory.annotation.Required;
import org.springframework.security.core.Authentication;
import org.springframework.security.web.authentication.AuthenticationSuccessHandler;
public class MyAuthenticationSuccessHandler implements AuthenticationSuccessHandler {
private static final Log log = LogFactory.getLog(MyAuthenticationSuccessHandler.class);
private JsonHelper jsonHelper;
private UserService userService;
@Required
public void setJsonHelper(JsonHelper jsonHelper) {
this.jsonHelper = jsonHelper;
}
@Required
public void setUserService(UserService userService) {
this.userService = userService;
}
@Override
public void onAuthenticationSuccess(
HttpServletRequest request,
HttpServletResponse response,
Authentication authentication)
throws IOException, ServletException {
try {
String email = (String) authentication.getName();
User u = userService.findByEmail(email);
HttpSession session = request.getSession();
session.setAttribute("userId", u.getId());
if (response.isCommitted()) {
log.debug("Response committed, cannot return content.");
return;
}
jsonHelper.sendJson(response, "ok", SC_OK, "Successfully logged in.");
} catch (Exception ex) {
throw new RuntimeException(ex);
}
}
}
import java.io.IOException;
import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.springframework.beans.factory.annotation.Required;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.web.AuthenticationEntryPoint;
import org.springframework.security.web.access.ExceptionTranslationFilter;
import org.springframework.security.web.savedrequest.RequestCache;
/*
* From: http://www.to-string.com/2012/08/04/springsecurity-authenticating-authorizing-ajax-requests-server-side-implementation/
*/
public class MyExceptionTranslationFilter extends ExceptionTranslationFilter {
private JsonHelper jsonHelper;
@Required
public void setJsonHelper(JsonHelper jsonHelper) {
this.jsonHelper = jsonHelper;
}
@SuppressWarnings("deprecation")
public MyExceptionTranslationFilter() {
super();
}
public MyExceptionTranslationFilter(AuthenticationEntryPoint authenticationEntryPoint) {
super(authenticationEntryPoint);
}
public MyExceptionTranslationFilter(AuthenticationEntryPoint authenticationEntryPoint, RequestCache requestCache) {
super(authenticationEntryPoint, requestCache);
}
@Override
protected void sendStartAuthentication(
HttpServletRequest req, HttpServletResponse resp, FilterChain chain,
AuthenticationException reason)
throws ServletException, IOException {
jsonHelper.sendJson(response, "nauth", HttpServletResponse.SC_UNAUTHORIZED, "Not authorized.");
}
}
import static javax.servlet.http.HttpServletResponse.SC_OK;
import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.springframework.beans.factory.annotation.Required;
import org.springframework.security.core.Authentication;
import org.springframework.security.web.authentication.logout.LogoutSuccessHandler;
public class MyLogoutSuccessHandler implements LogoutSuccessHandler {
private JsonHelper jsonHelper;
@Required
public void setJsonHelper(JsonHelper jsonHelper) {
this.jsonHelper = jsonHelper;
}
@Override
public void onLogoutSuccess(
HttpServletRequest request, HttpServletResponse response,
Authentication authentication)
throws IOException, ServletException {
jsonHelper.sendJson(response, "ok", SC_OK, "Successfully logged out.");
}
}
<?xml version="1.0" encoding="UTF-8"?>
<!--
Advanced customizations of the Spring Security configuration.
For when the defaults brought by the <http> elements are not enough.
http://blog.springsource.org/2010/03/06/behind-the-spring-security-namespace/
-->
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:sec="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.xsd
http://www.springframework.org/schema/security
http://www.springframework.org/schema/security/spring-security.xsd">
<bean id="authenticationManager" class="org.springframework.security.authentication.ProviderManager">
<property name="providers">
<list>
<ref bean="authenticationProvider" />
<ref bean="anonymousProvider" />
</list>
</property>
</bean>
<bean id="authenticationProvider" class="org.springframework.security.authentication.dao.DaoAuthenticationProvider">
<property name="passwordEncoder">
<bean id="passwordEncoder" class="org.springframework.security.authentication.encoding.ShaPasswordEncoder" />
</property>
<property name="userDetailsService" ref="userService" />
</bean>
<bean id="anonymousProvider" class="org.springframework.security.authentication.AnonymousAuthenticationProvider">
<property name="key" value="SomeUniqueKeyForThisApplication" />
</bean>
<!--
Ref: http://static.springsource.org/spring-security/site/docs/3.1.x/reference/appendix-namespace.html#nsa-jdbc-user-service
-->
<sec:jdbc-user-service
id="userService"
authorities-by-username-query="
select email as username,
'USER' as authority
from users u
where lower(u.email) = lower(?)
"
users-by-username-query="
select email as username,
passwd_sha1 as password,
enabled as enabled
from users u
where lower(u.email) = lower(?)
"
role-prefix="ROLE_"
data-source-ref="backendDS" /> <!-- definido na lib backend.jar -->
<alias name="filterChainProxy" alias="springSecurityFilterChain"/>
<bean id="filterChainProxy" class="org.springframework.security.web.FilterChainProxy">
<sec:filter-chain-map path-type="ant">
<sec:filter-chain pattern="/**"
filters="securityContextFilter,
logoutFilter,
formLoginFilter,
requestCacheFilter,
servletApiFilter,
anonFilter,
sessionMgmtFilter,
exceptionTranslator,
filterSecurityInterceptor" />
</sec:filter-chain-map>
</bean>
<bean id="securityContextFilter" class="org.springframework.security.web.context.SecurityContextPersistenceFilter" >
<property name="securityContextRepository" ref="securityContextRepository" />
</bean>
<bean id="securityContextRepository"
class="org.springframework.security.web.context.HttpSessionSecurityContextRepository" />
<bean id="logoutFilter" class="org.springframework.security.web.authentication.logout.LogoutFilter">
<constructor-arg>
<bean class="myapp.filter.MyLogoutSuccessHandler">
<property name="authResultHandler" ref="authResultHandler" />
</bean>
</constructor-arg>
<constructor-arg>
<list><bean class="org.springframework.security.web.authentication.logout.SecurityContextLogoutHandler" /></list>
</constructor-arg>
<property name="filterProcessesUrl" value="/logout" />
</bean>
<bean id="authResultHandler" class="myapp.filter.AuthResultHandler" />
<bean id="formLoginFilter" class="org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter">
<property name="authenticationManager" ref="authenticationManager" />
<property name="authenticationSuccessHandler">
<bean class="myapp.filter.MyAuthenticationSuccessHandler">
<property name="authResultHandler" ref="authResultHandler" />
<property name="clienteService" ref="clienteService" />
</bean>
</property>
<property name="authenticationFailureHandler">
<bean class="myapp.filter.MyAuthenticationFailureHandler">
<property name="authResultHandler" ref="authResultHandler" />
</bean>
</property>
<property name="sessionAuthenticationStrategy">
<bean class="org.springframework.security.web.authentication.session.SessionFixationProtectionStrategy" />
</property>
<property name="filterProcessesUrl" value="/security_check" />
</bean>
<bean id="requestCacheFilter" class="org.springframework.security.web.savedrequest.RequestCacheAwareFilter" />
<bean id="servletApiFilter" class="org.springframework.security.web.servletapi.SecurityContextHolderAwareRequestFilter" />
<bean id="anonFilter" class="org.springframework.security.web.authentication.AnonymousAuthenticationFilter" >
<property name="key" value="SomeUniqueKeyForThisApplication" />
<property name="userAttribute" value="anonymousUser,ROLE_ANONYMOUS" />
</bean>
<bean id="sessionMgmtFilter" class="org.springframework.security.web.session.SessionManagementFilter" >
<constructor-arg ref="securityContextRepository" />
</bean>
<bean id="exceptionTranslator"
class="myapp.filter.MyExceptionTranslationFilter">
<constructor-arg index="0"
type="org.springframework.security.web.AuthenticationEntryPoint">
<bean class="org.springframework.security.web.authentication.LoginUrlAuthenticationEntryPoint">
<property name="loginFormUrl" value="/login"/>
</bean>
</constructor-arg>
<property name="authResultHandler" ref="authResultHandler" />
</bean>
<bean id="filterSecurityInterceptor" class="org.springframework.security.web.access.intercept.FilterSecurityInterceptor">
<property name="securityMetadataSource">
<sec:filter-security-metadata-source>
<sec:intercept-url pattern="/" access="IS_AUTHENTICATED_ANONYMOUSLY" />
<sec:intercept-url pattern="/login" access="IS_AUTHENTICATED_ANONYMOUSLY" />
<sec:intercept-url pattern="/rev" access="IS_AUTHENTICATED_ANONYMOUSLY" />
<sec:intercept-url pattern="/admin/**" access="ROLE_ADMIN" />
<sec:intercept-url pattern="/**" access="ROLE_USER" />
</sec:filter-security-metadata-source>
</property>
<property name="authenticationManager" ref="authenticationManager" />
<property name="accessDecisionManager" ref="accessDecisionManager" />
</bean>
<bean id="accessDecisionManager" class="org.springframework.security.access.vote.AffirmativeBased">
<property name="decisionVoters">
<list>
<bean class="org.springframework.security.access.vote.RoleVoter"/>
<bean class="org.springframework.security.access.vote.AuthenticatedVoter"/>
</list>
</property>
</bean>
<bean id="webPrivilegeEvaluator" class="org.springframework.security.web.access.DefaultWebInvocationPrivilegeEvaluator">
<constructor-arg ref="filterSecurityInterceptor" />
</bean>
</beans>
<!-- Spring security should intercept all URLs. -->
<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>
<!--
All the other files are for handling login attempts. However, for URLs declared in the spring security files, spring security will send an error 403 if
access is not authorized. Your web.xml should be prepared to handle that.
-->
<error-page>
<error-code>403</error-code>
<location>/WEB-INF/jsp/403.jsp</location>
</error-page>
@rcardin
Copy link

rcardin commented Nov 24, 2016

You saved my day! Thanks a lot!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment