这两天Spring用户登录国际化这个问题困扰我好久啊,于昨天晚上终于把它干掉了。
场景就是我们公司的产品-incopat,需要支持中英文,用户登录这块用的spring自带的security,需求讲的通俗一点就是,中文版提示中文提示信息,英文版提示英文版信息,废话不多说,见代码。
首先配置文件
security-config.xml
<beans:bean id="customUsernamePasswordAuthenticationFilter"
class="com.incoshare.base.security.CustomUsernamePasswordAuthenticationFilter"
p:authenticationManager-ref="authenticationManager"
p:filterProcessesUrl="/doLogin" p:sessionAuthenticationStrategy-ref="compositeSessionAuthenticationStrategy"
p:authenticationSuccessHandler-ref="authenticationSuccessHandler"
p:authenticationFailureHandler-ref="authenticationFailureHandler"
p:rememberMeServices-ref="rememberMeServices"
p:authenticationDetailsSource-ref="customWebAuthenticationDetailsSource">
</beans:bean> <beans:bean id="messageSource"
class="org.springframework.context.support.ReloadableResourceBundleMessageSource">
<beans:property name="basename"
value="classpath:messages/security/messages" />
</beans:bean>
配置文件只贴了关键部分,第一个bean 配置登录的过滤器,第二个bean加载messages文件(这里有需要注意的地方如果想引用自己的message文件,建好文件后提供相对地址就可以了,classpath必须要哦!文件命名也是有规则的,message_en 就是下划线带上语言简称,这个简称需要跟网站上切换中英文标示一致),配置文件就这些
下面贴上过滤器代码
package com.incoshare.base.security; import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse; import com.incoshare.base.util.PropertyUtil;
import com.incoshare.base.util.Utils;
import com.incoshare.incopat4.model.User;
import com.incoshare.incopat4.service.usermanager.UserListService;
import com.incoshare.util.EncryptUtils;
import com.incoshare.util.SingleLoginUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.i18n.LocaleContextHolder;
import org.springframework.security.authentication.AuthenticationServiceException;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;
import org.springframework.util.StringUtils;
import org.springframework.web.servlet.i18n.SessionLocaleResolver;
import org.springframework.web.util.WebUtils; import com.incoshare.base.util.RegexUtil; import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Locale; public class CustomUsernamePasswordAuthenticationFilter extends UsernamePasswordAuthenticationFilter{ static Logger logger = LoggerFactory
.getLogger(CustomUsernamePasswordAuthenticationFilter.class); private boolean postOnly = true; private byte[] keyBytes = { 0x21, 0x12, 0x4F, 0x58, (byte) 0x88, 0x09, 0x40, 0x38, 0x74,
0x25, (byte) 0x99, 0x21, (byte) 0xCB, (byte) 0xDD, 0x58, 0x66, 0x77, 0x22, 0x74,
(byte) 0x98, 0x30, 0x40, 0x36, (byte) 0xE2 };
private byte[] keyBytesForSjz = { 0x22, 0x12, 0x4F, 0x58, (byte) 0x88, 0x09, 0x40, 0x38, 0x74,
0x25, (byte) 0x99, 0x21, (byte) 0xCB, (byte) 0xDD, 0x48, 0x66, 0x77, 0x22, 0x74,
(byte) 0x98, 0x30, 0x40, 0x36, (byte) 0xE2 };
@Autowired
UserListService userListService;
@Autowired
PropertyUtil propertyUtil; @Override
public Authentication attemptAuthentication(HttpServletRequest request, HttpServletResponse response) throws AuthenticationException { String newLocale = request.getParameter("locallangue");
if (newLocale != null) {
Locale locale = StringUtils.parseLocaleString(newLocale);
WebUtils.setSessionAttribute(request,
SessionLocaleResolver.LOCALE_SESSION_ATTRIBUTE_NAME, locale);
LocaleContextHolder.setLocale(locale, true);
}
//这块代码就是通过获取前台返回的语言编码,设置到spring的localeContextHolder里
if (postOnly && !request.getMethod().equals("POST")) {
throw new AuthenticationServiceException("Authentication method not supported: " + request.getMethod());
} String username = obtainUsername(request);
String password = obtainPassword(request); //集慧智佳用户登录
String token = request.getParameter("token");
//石家庄单点登录
String tokenForSjz = request.getParameter("tokenForSjz");
if(Utils.isNotNull(token) || Utils.isNotNull(tokenForSjz)){
boolean judge = true;
if(Utils.isNull(token)){
judge = false;
}
SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH");
Date date = new Date();
String dateStr = simpleDateFormat.format(date);
String decodeToken = "";
String decryptJudge = "";
if(judge){
decodeToken = EncryptUtils.DataDecrypt(keyBytes, token);
decryptJudge = token;
}else{
decodeToken = EncryptUtils.DataDecrypt(keyBytesForSjz, tokenForSjz);
decryptJudge = tokenForSjz;
};
if(!decodeToken.equals(decryptJudge.trim()) && decodeToken.equals(dateStr.trim())){ User user = userListService.queryUserJhzj(username);
if(Utils.isNotNull(user)){
if(Utils.isNotNull(user.getOrganizationId())){
if(judge){
String jhzjOrid=propertyUtil.getContextProperty("jhzjOrid");
String pwd = propertyUtil.getContextProperty("jhzjPassword").trim();
if(user.getOrganizationId().equals(Integer.parseInt(jhzjOrid.trim()))){
password = pwd;
}
}else{
if(Utils.isNotNull(password)){
String record = password;
String orid = propertyUtil.getContextProperty("sjzOrid").trim();
password = EncryptUtils.DataDecrypt(keyBytesForSjz,password);
if(record.equals(password) || !String.valueOf(user.getOrganizationId()).equals(orid)){
password = "";
}
}
} }
} }else{
password = "";
}
} String tokenForLogin = request.getParameter("tokenForLogin");
if(Utils.isNotNull(tokenForLogin)){
String companyName = request.getParameter("companyName");
String record = password;
tokenForLogin = tokenForLogin.replaceAll(" ","+");
password = SingleLoginUtils.decryptPassword(username,password,tokenForLogin,companyName,userListService,propertyUtil,logger);
if(Utils.isNull(password)){
logger.info("{}:密码解密为空。账号{},没有解密的密码:{}",companyName,username,record);
}
}
if (username == null) {
username = "";
} if (password == null) {
password = "";
} username = username.trim(); UsernamePasswordAuthenticationToken authRequest = new UsernamePasswordAuthenticationToken(username, password); if(!StringUtils.isEmpty(request.getParameter("iplogin"))) {
username = RegexUtil.getRealIp(request);
password="";
authRequest = new IpUserAuthenticationToken(username,password);
} this.logger.info("user:{},ip:{} trying to login",new Object[]{username,RegexUtil.getRealIp(request)}); // Allow subclasses to set the "details" property
setDetails(request, authRequest); return this.getAuthenticationManager().authenticate(authRequest);
}
}
这块先声明下,代码不是我写的,看着很乱很糟糕吧。主要上边标黄的两个地方就可以了。
值设置后会通过this.getAuthenticationManager().authenticate(authRequest) 去初始化,喜欢研究源码的朋友看一跟一下看看
org.springframework.context.i18n.LocaleContextHolder这个类
public static LocaleContext getLocaleContext() {
LocaleContext localeContext = localeContextHolder.get();
if (localeContext == null) {
localeContext = inheritableLocaleContextHolder.get();//这里会把你设置的值放到Spring 容器
}
return localeContext;
}
好了,关键的地方都说完了,这几天搞了这么久,写完了也没多少东西,代码就是这么美妙,解决问题的过程是漫长苦恼的,但最终解决有可能就一两行代码的事。
关于这一块有问题的可以随时沟通。
Spring security实现国际化问题的更多相关文章
-
Spring Security简明实践及相关国际化处理
别人的都是最佳实践,因为我目前的设置没有按照参考文档推荐,还是采用DelegatingFilterProxy,所以我只能说简明实践.先贴我的applicationContext-security.xm ...
-
Spring Security OAuth2 开发指南
官方原文:http://projects.spring.io/spring-security-oauth/docs/oauth2.html 翻译及修改补充:Alex Liao. 转载请注明来源:htt ...
-
spring mvc 和spring security配置 web.xml设置
<?xml version="1.0" encoding="UTF-8"?> <web-app xmlns="http://xmln ...
-
SPRING SECURITY JAVA配置:Web Security
在前一篇,我已经介绍了Spring Security Java配置,也概括的介绍了一下这个项目方方面面.在这篇文章中,我们来看一看一个简单的基于web security配置的例子.之后我们再来作更多的 ...
-
【OAuth2.0】Spring Security OAuth2.0篇之初识
不吐不快 因为项目需求开始接触OAuth2.0授权协议.断断续续接触了有两周左右的时间.不得不吐槽的,依然是自己的学习习惯问题,总是着急想了解一切,习惯性地钻牛角尖去理解小的细节,而不是从宏观上去掌握 ...
-
spring security oauth2.0 实现
oauth应该属于security的一部分.关于oauth的的相关知识可以查看阮一峰的文章:http://www.ruanyifeng.com/blog/2014/05/oauth_2_0.html ...
-
Spring Security(08)——intercept-url配置
http://elim.iteye.com/blog/2161056 Spring Security(08)--intercept-url配置 博客分类: spring Security Spring ...
-
Spring Security控制权限
Spring Security控制权限 1,配置过滤器 为了在项目中使用Spring Security控制权限,首先要在web.xml中配置过滤器,这样我们就可以控制对这个项目的每个请求了. < ...
-
Spring Security笔记:Hello World
本文演示了Spring Security的最最基本用法,二个页面(或理解成二个url),一个需要登录认证后才能访问(比如:../admin/),一个可匿名访问(比如:../welcome) 注:以下内 ...
随机推荐
-
mysql - 最小缺失值查询
初始化数据 DROP TABLE IF EXISTS X; CREATE TABLE X( a INT UNSIGNED PRIMARY KEY, b ) NOT NULL )ENGINE=INNOD ...
-
用360安全浏览器控制网速,调试loading
360安全浏览器 按f12 两个按钮的意思分别为禁止缓存,网络设置,这样就能控制网速了,调试loading了
-
HDU 1230 火星A+B
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1230 水题模拟一道,主要考验代码能力,刷完题就感觉自己还是太弱了. #include<cmath ...
-
spring cloud 专题二(spring cloud 入门搭建 之 微服务搭建和注册)
一.前言 本文为spring cloud 微服务框架专题的第二篇,主要讲解如何快速搭建微服务以及如何注册. 本文理论不多,主要是傻瓜式的环境搭建,适合新手快速入门. 为了更好的懂得原理,大家可以下载& ...
-
19-matlab知识点复习二
%% function RandDisplayJiong axis off; %关闭坐标轴 %Menubar是菜单条 none就是不显示图上方的菜单条 set(gcf,'menubar','none' ...
-
对mysql数据库中字段为空的处理
数据库中字段为空的有两种:一种为null,另一种为空字符串.null代表数值未知,空字符串是有值得,只是为空.有时间我们想把数据库中的数据以excel形式导出时 如果碰到字段为空的,为空的字段会被后面 ...
-
java jar 包加载文件问题
场景: A 项目是一个服务,然后部署到本地 maven 仓库里,然后 B 项目依赖 A 项目,调用 A 项目的方法,但是发现,报错,说找不到文件(config.xsv).这就很奇怪了,怎么会呢, ...
-
步步为营-22-xml登录
说明:通过xml完成用户登录信息的判断 1 搭建UI页面 2 新建一个student类,类中包含以上属性 public class Student { public int ID { get; set ...
-
Non-negative Matrix Factorization 非负矩阵分解
著名的科学杂志<Nature>于1999年刊登了两位科学家D.D.Lee和H.S.Seung对数学中非负矩阵研究的突出成果.该文提出了一种新的矩阵分解思想――非负矩阵分解(Non-nega ...
-
php tools 破解
default.aspx <%@ Page Language="C#" %><% string selfKey = "<RSAKeyValue&g ...