spring cas defaultsavedrequestparam default 什么时候存的

博客分类:
1 配置文件 security-ns.xml
&?xml version="1.0" encoding="UTF-8"?&
&beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:security="http://www.springframework.org/schema/security"
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:http pattern="/openapi/**" security="none" /&
&security:http pattern="/useraccounts/userprofile.json" security="none" /&
&security:http pattern="/useraccounts/register**" security="none" /&
//entry-point-ref 配置自定义登录
&security:http auto-config="false" entry-point-ref="authenticationEntryPoint"&
&security:intercept-url pattern="/backManage/**" access="ROLE_BACK_USER" /&
&security:intercept-url pattern="/mall/**"
access="ROLE_BACK_USER" /&
&security:intercept-url pattern="/thirdUser/**"
access="ROLE_USER" /&
&security:intercept-url pattern="/useraccounts/**" access="ROLE_USER" /&
&security:intercept-url pattern="/cart/**.html" access="ROLE_USER" /&
&security:intercept-url pattern="/ticket/**" access="ROLE_USER,ROLE_BACK_USER" /&
&security:intercept-url pattern="/order/**" access="ROLE_USER" /&
&security:intercept-url pattern="/comment/**" access="ROLE_USER" /&
&security:intercept-url pattern="/personal/**" access="ROLE_USER" /&
&security:intercept-url pattern="/favorite/**" access="ROLE_USER" /&
//需要替换的Filter顺序,配置自定义custom-filter时必须蔣auto-config="false",不然会报已经存在同样的过滤器错误
&security:custom-filter ref="myLoginFilter"
position="FORM_LOGIN_FILTER" /&
//登出配置
&security:logout logout-success-url="${local.service.url}"/&
&/security:http&
//密码加密工具类
&bean id="encoder" class="org.springframework.security.authentication.encoding.ShaPasswordEncoder"/&
//认证管理器
&security:authentication-manager alias="authenticationManager"&
//UserDetailsService实现 主要用于用户的查询
&security:authentication-provider user-service-ref="userLoginService"&
&security:password-encoder
ref="encoder"&
&/security:password-encoder&
&/security:authentication-provider&
&/security:authentication-manager&
&bean id="myLoginFilter" class="com.sale114.www.sercurity.MyUsernamePasswordAuthenticationFilter"&
&property name="authenticationManager" ref="authenticationManager"/&
&property name="authenticationFailureHandler" ref="failureHandler"/&
&property name="authenticationSuccessHandler" ref="successHandler"/&
//成功登录后
&bean id="successHandler" class="com.sale114.www.sercurity.MySavedRequestAwareAuthenticationSuccessHandler"&
&property name="defaultTargetUrl" value="${local.service.url}"/&
//登录失败
&bean id="failureHandler" class="com.sale114.www.sercurity.MySimpleUrlAuthenticationFailureHandler"&
&property name="defaultFailureUrl" value="${local.service.url}/login.html?validated=false"/&
&bean id="authenticationEntryPoint"
class="org.springframework.security.web.authentication.LoginUrlAuthenticationEntryPoint"&
&property name="loginFormUrl" value="${local.service.url}/login.html" /&
2 UserLoginServiceImpl 查询用户实现类
@Named("userLoginService")
public class UserLoginServiceImpl
implements UserDetailsService ,LoginService{
private UserLoginDAO userLoginDAO;
public WrappedUserLogin getUserLogin() {
WrappedUserLogin wrappedUserLogin = (WrappedUserLogin) SecurityContextHolder
.getContext().getAuthentication().getPrincipal();
return wrappedUserL
} catch (Exception e) {
public UserDetails loadUserByUsername(String username)
throws UsernameNotFoundException {
System.out.println("用户名-------------"+username);
UserLogin userLogin =
if(username != null && !"".equals(username)&& username.indexOf("@") & 0){
userLogin = userLoginDAO.findByEmail(username);
username = userLogin.getNick();
userLogin = userLoginDAO.findByNick(username);
System.out.println("user is null ---"+userLogin.getUserType());
String nick = userLogin.getNick();
String email = userLogin.getEmail();
String mobile = userLogin.getMobile();
int userType = userLogin.getUserType();
List&GrantedAuthority& resultAuths = new ArrayList&GrantedAuthority&();
// 前台用户
if (userType == 1) {
resultAuths.add(new SimpleGrantedAuthority("ROLE_USER"));
resultAuths.add(new SimpleGrantedAuthority("ROLE_BACK_USER"));
return new WrappedUserLogin(userLogin.getId(), email, nick, mobile, userLogin.getPassword(), userType,resultAuths);
3 重写用户名密码验证
public class MyUsernamePasswordAuthenticationFilter extends UsernamePasswordAuthenticationFilter{
public static final String SPRING_SECURITY_FORM_USERNAME_KEY = "j_username";
public static final String SPRING_SECURITY_FORM_PASSWORD_KEY = "j_password";
//需要回调的URL 自定义参数
public static final String SPRING_SECURITY_FORM_REDERICT_KEY = "spring-security-redirect";
* @deprecated If you want to retain the username, cache it in a customized {@code AuthenticationFailureHandler}
@Deprecated
public static final String SPRING_SECURITY_LAST_USERNAME_KEY = "SPRING_SECURITY_LAST_USERNAME";
private String usernameParameter = SPRING_SECURITY_FORM_USERNAME_KEY;
private String passwordParameter = SPRING_SECURITY_FORM_PASSWORD_KEY;
private String redirectParameter = SPRING_SECURITY_FORM_REDERICT_KEY;
private boolean postOnly =
//~ Constructors ===================================================================================================
public MyUsernamePasswordAuthenticationFilter() {
//~ Methods ========================================================================================================
public Authentication attemptAuthentication(HttpServletRequest request, HttpServletResponse response) throws AuthenticationException {
if (postOnly && !request.getMethod().equals("POST")) {
throw new AuthenticationServiceException("Authentication method not supported: " + request.getMethod());
String username = obtainUsername(request);
String password = obtainPassword(request);
String redirectUrl = obtainRedercitUrl(request);
if (username == null) {
username = "";
if (password == null) {
password = "";
//自定义回调URL,若存在则放入Session
if(redirectUrl != null && !"".equals(redirectUrl)){
request.getSession().setAttribute("callCustomRediretUrl", redirectUrl);
username = username.trim();
UsernamePasswordAuthenticationToken authRequest = new UsernamePasswordAuthenticationToken(username, password);
// Allow subclasses to set the "details" property
setDetails(request, authRequest);
return this.getAuthenticationManager().authenticate(authRequest);
* Enables subclasses to override the composition of the password, such as by including additional values
* and a separator.&p&This might be used for example if a postcode/zipcode was required in addition to the
* password. A delimiter such as a pipe (|) should be used to separate the password and extended value(s). The
* &code&AuthenticationDao&/code& will need to generate the expected password in a corresponding manner.&/p&
* @param request so that request attributes can be retrieved
* @return the password that will be presented in the &code&Authentication&/code& request token to the
&code&AuthenticationManager&/code&
protected String obtainPassword(HttpServletRequest request) {
return request.getParameter(passwordParameter);
* Enables subclasses to override the composition of the username, such as by including additional values
* and a separator.
* @param request so that request attributes can be retrieved
* @return the username that will be presented in the &code&Authentication&/code& request token to the
&code&AuthenticationManager&/code&
protected String obtainUsername(HttpServletRequest request) {
return request.getParameter(usernameParameter);
protected String obtainRedercitUrl(HttpServletRequest request) {
return request.getParameter(redirectParameter);
* Provided so that subclasses may configure what is put into the authentication request's details
* property.
* @param request that an authentication request is being created for
* @param authRequest the authentication request object that should have its details set
protected void setDetails(HttpServletRequest request, UsernamePasswordAuthenticationToken authRequest) {
authRequest.setDetails(authenticationDetailsSource.buildDetails(request));
* Sets the parameter name which will be used to obtain the username from the login request.
* @param usernameParameter the parameter name. Defaults to "j_username".
public void setUsernameParameter(String usernameParameter) {
Assert.hasText(usernameParameter, "Username parameter must not be empty or null");
this.usernameParameter = usernameP
* Sets the parameter name which will be used to obtain the password from the login request..
* @param passwordParameter the parameter name. Defaults to "j_password".
public void setPasswordParameter(String passwordParameter) {
Assert.hasText(passwordParameter, "Password parameter must not be empty or null");
this.passwordParameter = passwordP
* Defines whether only HTTP POST requests will be allowed by this filter.
* If set to true, and an authentication request is received which is not a POST request, an exception will
* be raised immediately and authentication will not be attempted. The &tt&unsuccessfulAuthentication()&/tt& method
* will be called as if handling a failed authentication.
* Defaults to &tt&true&/tt& but may be overridden by subclasses.
public void setPostOnly(boolean postOnly) {
this.postOnly = postO
4 SimpleUrlAuthenticationSuccessHandler重写
public class MySavedRequestAwareAuthenticationSuccessHandler extends SimpleUrlAuthenticationSuccessHandler{
@Value(value = "${local.service.url}")
private String LOCAL_SERVER_URL;
protected final Log logger = LogFactory.getLog(this.getClass());
private RequestCache requestCache = new HttpSessionRequestCache();
public void onAuthenticationSuccess(HttpServletRequest request, HttpServletResponse response,
Authentication authentication) throws ServletException, IOException {
SavedRequest savedRequest = requestCache.getRequest(request, response);
if (savedRequest == null) {
System.out.println("savedRequest is null ");
//用户判断是否要使用上次通过session里缓存的回调URL地址
int flag = 0;
//通过提交登录请求传递需要回调的URL callCustomRediretUrl
if(request.getSession().getAttribute("callCustomRediretUrl") != null && !"".equals(request.getSession().getAttribute("callCustomRediretUrl"))){
String url = String.valueOf(request.getSession().getAttribute("callCustomRediretUrl"));
//若session 存在则需要使用自定义回调的URL 而不是缓存的URL
super.setDefaultTargetUrl(url);
super.setAlwaysUseDefaultTargetUrl(true);
request.getSession().setAttribute("callCustomRediretUrl", "");
//重设置默认URL为主页地址
super.setDefaultTargetUrl(LOCAL_SERVER_URL);
super.onAuthenticationSuccess(request, response, authentication);
//targetUrlParameter 是否存在
String targetUrlParameter = getTargetUrlParameter();
if (isAlwaysUseDefaultTargetUrl() || (targetUrlParameter != null && StringUtils.hasText(request.getParameter(targetUrlParameter)))) {
requestCache.removeRequest(request, response);
super.setAlwaysUseDefaultTargetUrl(false);
super.setDefaultTargetUrl("/");
super.onAuthenticationSuccess(request, response, authentication);
//清除属性
clearAuthenticationAttributes(request);
// Use the DefaultSavedRequest URL
String targetUrl = savedRequest.getRedirectUrl();
logger.debug("Redirecting to DefaultSavedRequest Url: " + targetUrl);
if(targetUrl != null && "".equals(targetUrl)){
targetUrl = LOCAL_SERVER_URL;
getRedirectStrategy().sendRedirect(request, response, targetUrl);
public void setRequestCache(RequestCache requestCache) {
this.requestCache = requestC
5 认证失败控制类重写
* &tt&AuthenticationFailureHandler&/tt& which performs a redirect to the value of the {@link #setDefaultFailureUrl
* defaultFailureUrl} property when the &tt&onAuthenticationFailure&/tt& method is called.
* If the property has not been set it will send a 401 response to the client, with the error message from the
* &tt&AuthenticationException&/tt& which caused the failure.
* If the {@code useForward} property is set, a {@code RequestDispatcher.forward} call will be made to
* the destination instead of a redirect.
* @author Luke Taylor
* @since 3.0
public class MySimpleUrlAuthenticationFailureHandler implements AuthenticationFailureHandler{
protected final Log logger = LogFactory.getLog(getClass());
private String defaultFailureU
private boolean forwardToDestination =
private boolean allowSessionCreation =
private RedirectStrategy redirectStrategy = new DefaultRedirectStrategy();
@Value(value = "${local.service.url}")
private String LOCAL_SERVER_URL;
public MySimpleUrlAuthenticationFailureHandler() {
public MySimpleUrlAuthenticationFailureHandler(String defaultFailureUrl) {
setDefaultFailureUrl(defaultFailureUrl);
* Performs the redirect or forward to the {@code defaultFailureUrl} if set, otherwise returns a 401 error code.
* If redirecting or forwarding, {@code saveException} will be called to cache the exception for use in
* the target view.
public void onAuthenticationFailure(HttpServletRequest request, HttpServletResponse response,
AuthenticationException exception) throws IOException, ServletException {
//认证失败区别前后台:LOGIN URL
if(request.getParameter("spring-security-redirect") != null){
request.getSession().setAttribute("callUrlFailure", request.getParameter("spring-security-redirect"));
//若有loginUrl 则重定向到后台登录界面
if(request.getParameter("loginUrl") != null && !"".equals(request.getParameter("loginUrl"))){
defaultFailureUrl = LOCAL_SERVER_URL+"/backlogin.html?validated=false";
//defaultFailureUrl 默认的认证失败回调URL
if (defaultFailureUrl == null) {
logger.debug("No failure URL set, sending 401 Unauthorized error");
response.sendError(HttpServletResponse.SC_UNAUTHORIZED, "Authentication Failed: " + exception.getMessage());
saveException(request, exception);
if (forwardToDestination) {
logger.debug("Forwarding to " + defaultFailureUrl);
request.getRequestDispatcher(defaultFailureUrl).forward(request, response);
logger.debug("Redirecting to " + defaultFailureUrl);
redirectStrategy.sendRedirect(request, response, defaultFailureUrl);
* Caches the {@code AuthenticationException} for use in view rendering.
* If {@code forwardToDestination} is set to true, request scope will be used, otherwise it will attempt to store
* the exception in the session. If there is no session and {@code allowSessionCreation} is {@code true} a session
* will be created. Otherwise the exception will not be stored.
protected final void saveException(HttpServletRequest request, AuthenticationException exception) {
if (forwardToDestination) {
request.setAttribute(WebAttributes.AUTHENTICATION_EXCEPTION, exception);
HttpSession session = request.getSession(false);
if (session != null || allowSessionCreation) {
request.getSession().setAttribute(WebAttributes.AUTHENTICATION_EXCEPTION, exception);
* The URL which will be used as the failure destination.
* @param defaultFailureUrl the failure URL, for example "/loginFailed.jsp".
public void setDefaultFailureUrl(String defaultFailureUrl) {
this.defaultFailureUrl = defaultFailureU
protected boolean isUseForward() {
return forwardToD
* If set to &tt&true&/tt&, performs a forward to the failure destination URL instead of a redirect. Defaults to
* &tt&false&/tt&.
public void setUseForward(boolean forwardToDestination) {
this.forwardToDestination = forwardToD
* Allows overriding of the behaviour when redirecting to a target URL.
public void setRedirectStrategy(RedirectStrategy redirectStrategy) {
this.redirectStrategy = redirectS
protected RedirectStrategy getRedirectStrategy() {
return redirectS
protected boolean isAllowSessionCreation() {
return allowSessionC
public void setAllowSessionCreation(boolean allowSessionCreation) {
this.allowSessionCreation = allowSessionC
6 登录Controller和页面省略
浏览 47374
浏览: 161804 次
来自: 成都
在那里解决呢
如何不需要账户就能登陆啊?我这边有这个需求,不需要输入用户名和 ...
你好。能给我发一份吗:
你好,能不能发我一份,邮箱:zzjjun.co ...
你好我做了分页 完了好了成功了;但是 后面突然不行了
调试发 ...login-webflow是当你在浏览器里面输入
后,cas server端如何处理的.
它实际上是spring-webflow的应用
有关spring-webflow的详细介绍,
网上铺天盖地,我就不啰嗦了
cas server端的web.xml文件里面有
&&servlet&&&&servlet-name&cas&/servlet-name&&&&servlet-class&&&&org.jasig.cas.web.init.SafeDispatcherServlet&&&/servlet-class&&&&init-param&&&&&param-name&publishContext&/param-name&&&&&param-value&false&/param-value&&&&/init-param&&&&load-on-startup&1&/load-on-startup&&&/servlet&
这个是login-webflow的入口servlet,映射的url-pattern之一就是
&servlet-mapping&&&&servlet-name&cas&/servlet-name&&&&url-pattern&/login&/url-pattern&&&/servlet-mapping&
spring webflow必须在flow-registry里面注册,
这个是在cas-servlet.xml里面注册的
&webflow:flow-registry id="flowRegistry" flow-builder-services="builder"&&&&&&&& &webflow:flow-location path="/WEB-INF/login-webflow.xml" id="login" /&&&& &/webflow:flow-registry&&
这句话把login-webflow.xml进行了注册
对应的view properties在propertyFileConfigurer.xml中指定了
&bean id="propertyPlaceholderConfigurer" class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer"&&p:location="/WEB-INF/cas.properties" /&
打开cas.properties
cas.themeResolver.defaultThemeName=defaultcas.viewResolver.basename=default_views
对应了default.properties
&&&&&&&& default_views.properties
这两个properties里面放了对应的css js 和jsp的路径,大家一定要注意。
OK,基本的配置就是这些,
下面我们重点来关注下login-webflow.xml
里面是一个具体的spring webflow流程
涉及到的结点有on-start 流程开始
end-state流程结束 decision-state判断,类似于if
view-state对应jsp页面 action-state对应执行程序的某段
里面的&evaluate expression="initialFlowSetupAction" /&这些定义在cas-servlet.xml中
view-state里面的view定义在default_views.properties中
下面简单介绍下里面的语句说明
&evaluate expression="initialFlowSetupAction" /&
这句话的意思是执行
org.jasig.cas.web.flow.InitialFlowSetupAction中的doExecute方法
其中的变量都由spring注入了
具体看对应的配置文件
然后下一个流程是
&decision-state id="ticketGrantingTicketExistsCheck"&&&&if test="flowScope.ticketGrantingTicketId neq null" then="hasServiceCheck" else="gatewayRequestCheck" /&&&/decision-state&
flowScope.ticketGrantingTicketId
这个在org.jasig.cas.web.flow.InitialFlowSetupAction中由
context.getFlowScope().put(&&&&&&&&&&& "ticketGrantingTicketId", this.ticketGrantingTicketCookieGenerator.retrieveCookieValue(request));
这句话放入了,然后在这儿进行检测neq null是不为null的意思
then else都很好理解
view state
&view-state id="viewLoginForm" view="casLoginView" model="credentials"&&&&&&&& &var name="credentials" class="org.jasig.cas.authentication.principal.UsernamePasswordCredentials" /&&&&&&&& &binder&&&&&&&&&&&& &binding property="username" /&&&&&&&&&&&& &binding property="password" /&&&&&&&& &/binder&&&&&&&& &on-entry&&&&&&&&&&&& &set name="mandName" value="'credentials'" /&&&&&&&& &/on-entry&&&&transition on="submit" bind="true" validate="true" to="realSubmit"&&&&&&&&&&&& &set name="flowScope.credentials" value="credentials" /&&&&&&&&&&&& &evaluate expression="authenticationViaFormAction.doBind(flowRequestContext, flowScope.credentials)" /&&&&&&&& &/transition&&&/view-state&
对应的是casLoginView.jsp
在这里对一些页面变量和对应的java类进行了绑定
action state
&action-state id="realSubmit"&&&&&&&& &evaluate expression="authenticationViaFormAction.submit(flowRequestContext, flowScope.credentials, messageContext)" /&&&&transition on="warn" to="warn" /&&&&transition on="success" to="sendTicketGrantingTicket" /&&&&transition on="error" to="viewLoginForm" /&&&/action-state&
执行对应的方法,这儿执行org.jasig.cas.web.flow.AuthenticationViaFormAction中的
submit方法,并根据返回值到不同的分支
这块要弄清楚不容易,建议多看看相关资料,
里面倒腾还是很多的。
本文已收录于以下专栏:
相关文章推荐
1.执行initialFlowSetupAction的doExecute(final RequestContext context)方法。
参数RequestContex...
参考链接:/AloneSword/p/3360106.html
在CAS中MVC的控制主要是使用的spring MVC来实现的。但是,在登录过程中,因为有...
一、Tomcat配置SSL1. 生成 server key以命令方式换到目录%TOMCAT_HOME%,在command命令行输入如下命令:
keytool -genkey -alias tomca...
应需求的变化,在登录cas的时候,默认根据用户名和密码进行验证,如果加上用户名,密码和一个系统标识进行验证呢?该如何做呢?
我们知道cas默认的登录界面中,输入的用户名和密码,再配置一下deploy...
假设cas server服务地址:http://cas-server:8080/cas
cas client集成的应用地址:http://cas-client:8070/castest
一、不落俗套的开始1、背景介绍单点登录:Single Sign On,简称SSO,SSO使得在多个应用系统中,用户只需要登录一次就可以访问所有相互信任的应用系统。CAS框架:CAS(Central A...
有时候需要删除 Solr 中的数据(特别是不重做索引的系统中,在重做索引期间)。删除一些 Solr 无效数据(或不合格数据)。
删除 solr 中的数据有几种方式:
1、先来看 curl 方式:...
有了前面的基础,现在可以开始cas server端的部署了。首先大家可以去http://www.jasig.org/cas/download上下载cas的最新server端和client端这里我们下载...
有几个相对独立的java的web应用系统, 各自有自己的登陆验证功能,用户在使用不同的系统的时候,需要登陆不同的系统。现在需要提供一个统一的登陆/登出界面, 而不修改各个系统原来的登陆验证机制...
Jasig cas(Central Authentication Service)官方站点:http://www.jasig.org/cas,访问这个站点需要翻墙。
cas官网文...
他的最新文章
讲师:王哲涵
讲师:王渊命
您举报文章:
举报原因:
原文地址:
原因补充:
(最多只允许输入30个字)

我要回帖

更多关于 shirosavedrequest 的文章

 

随机推荐