Spring security实现国际化问题
这两天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) 注:以下内 ...
随机推荐
- 天了噜,Java 8 要停止维护了!
前些天的中兴事件,已经让国人意识到自己核心技术的不足,这次的 JDK 8 对企业停止免费更新更是雪上加霜.. 以下是 Oracle 官网提示的 JDK8 终止更新公告. 原文内容:Oracle wil ...
- 遍历List集合的三种方法
List<String> list = new ArrayList<String>(); list.add("aaa"); list.add("b ...
- nginx介绍(二) - 默认配置
前言 前面, 在浏览器中, 输入linux 的ip, 出现了以下页面: 那这个页面在哪里呢? 一. 工具 notepad++ 在进入主题之前, 先来介绍下, 一会使用到的工具. 在notepad++里 ...
- Java对日期Date类进行日期加减运算,年份加减,月份加减
package com.cy; import java.security.InvalidParameterException; import java.text.ParseException; imp ...
- mysql查找一个字段属于哪个表
查询mid字段存在于哪个表中 SELECT TABLE_SCHEMA,TABLE_NAME FROM information_schema.`COLUMNS` WHERE COLUMN_NAME='m ...
- 绕过边界防火墙之ICMP隧道、HTTP隧道、UDP隧道
一.ICMP隧道 背景:已经通过某种手段拿到了园区网A主机的控制权,但是边界防火墙只放行该主机向外的ICMP流量,此时怎样才能让A主机和公网主机C建立TCP连接呢? 方案:将TCP包内容包裹在ICMP ...
- MyBatis从入门到放弃三:一对一关联查询
前言 简单来说在mybatis.xml中实现关联查询实在是有些麻烦,正是因为起框架本质是实现orm的半自动化. 那么mybatis实现一对一的关联查询则是使用association属性和resultM ...
- Shell 示例:利用 $RANDOM 产生随机整数
代码如下: #!/bin/bash # $RANDOM 在每次调用的时候,返回一个不同的随机整数 # 指定的范围是: 0 - 32767 MAXCOUNT=10 count=1 echo echo & ...
- centos6.5修改yum安装的mysql默认目录
0.说明 Linux下更改yum默认安装的mysql路径datadir. linux下,MySQL默认的数据文档存储目录为/var/lib/mysql. 假如要把MySQL目录移到/home/data ...
- js串口通信 调用MSCOMM32控件 链接电子秤(完整版实现方案)
硬件环境:RS232转USB串口线*1 电子秤*1(本人采用G&G E600Y-C型号称重仪) 电子秤原装RS232数据线*1 计算机*1 软件环境:RS232转USB串口线驱动(这个可以在串 ...