这两天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实现国际化问题的更多相关文章

  1. Spring Security简明实践及相关国际化处理

    别人的都是最佳实践,因为我目前的设置没有按照参考文档推荐,还是采用DelegatingFilterProxy,所以我只能说简明实践.先贴我的applicationContext-security.xm ...

  2. Spring Security OAuth2 开发指南

    官方原文:http://projects.spring.io/spring-security-oauth/docs/oauth2.html 翻译及修改补充:Alex Liao. 转载请注明来源:htt ...

  3. spring mvc 和spring security配置 web.xml设置

    <?xml version="1.0" encoding="UTF-8"?> <web-app xmlns="http://xmln ...

  4. SPRING SECURITY JAVA配置:Web Security

    在前一篇,我已经介绍了Spring Security Java配置,也概括的介绍了一下这个项目方方面面.在这篇文章中,我们来看一看一个简单的基于web security配置的例子.之后我们再来作更多的 ...

  5. 【OAuth2.0】Spring Security OAuth2.0篇之初识

    不吐不快 因为项目需求开始接触OAuth2.0授权协议.断断续续接触了有两周左右的时间.不得不吐槽的,依然是自己的学习习惯问题,总是着急想了解一切,习惯性地钻牛角尖去理解小的细节,而不是从宏观上去掌握 ...

  6. spring security oauth2.0 实现

    oauth应该属于security的一部分.关于oauth的的相关知识可以查看阮一峰的文章:http://www.ruanyifeng.com/blog/2014/05/oauth_2_0.html ...

  7. Spring Security(08)——intercept-url配置

    http://elim.iteye.com/blog/2161056 Spring Security(08)--intercept-url配置 博客分类: spring Security Spring ...

  8. Spring Security控制权限

    Spring Security控制权限 1,配置过滤器 为了在项目中使用Spring Security控制权限,首先要在web.xml中配置过滤器,这样我们就可以控制对这个项目的每个请求了. < ...

  9. Spring Security笔记:Hello World

    本文演示了Spring Security的最最基本用法,二个页面(或理解成二个url),一个需要登录认证后才能访问(比如:../admin/),一个可匿名访问(比如:../welcome) 注:以下内 ...

随机推荐

  1. Linux 定位网络不通问题

    [参考文章]:ping命令入门详解 1. ipconfig / ifconfig 1. 作用: 检查本地的网络配置是否正确 2. ping 1. 作用: 一个十分好用的TCP/IP工具.它主要的功能是 ...

  2. DevOps - CI - 持续集成(Continuous Integration)

    初见 持续集成是什么? 持续集成基础概念介绍 持续集成服务器与工具集 了解 敏捷开发中的持续集成 使用Jenkins进行持续集成 案例 gitlab+gerrit+jenkins持续集成框架 使用Ge ...

  3. Python内置类型(4)--数值

    Python有以下三种的数值类型: 整型(integers), 浮点型(floating point numbers), 以及 复数(complex numbers).此外,布尔是整数的子类型. 数值 ...

  4. 在向一个ArrayList中添加大量元素前,可以使用ensureCapacity方法来增加ArrayList的容量

    参考http://www.jianshu.com/p/f174d49b391c ensureCapacity(),该方法就是 ArrayList 的扩容方法.在前面就提过 ArrayList 每次新增 ...

  5. gitlab ssh_key

    ubuntu下生成git的密钥 1 生成ssh key 执行 命令 ssh-keygen -t rsa -C “wangwei@**.com.cn” 邮箱根据自己实际修改,一直回车 2 查看生成的密钥 ...

  6. Android Studio中设置一个按钮的不同点击触发事件

    my_day_model = (RelativeLayout) v.findViewById(R.id.my_day_model);my_day_pic = (ImageView) v.findVie ...

  7. TkMyBatis大杂烩

    1. 什么是TkMyBatis TkMyBatis是一个MyBatis的通用Mapper工具 2. 引入TkMyBatis到SpringBoot项目 以Gradle为例 compile 'tk.myb ...

  8. Re:从零开始的MySQL入门学习

    Linux作为操作系统,Apache作为Web服务器,MySQL作为数据库,PHP作为服务器端脚本解释器.由于这四个软件都是免费或开放式源码软件,因此使用这种不用花一分钱(人工成本除外)就可以建立起一 ...

  9. MySQL修改表、字段、库的字符集及字符集说明

    修改数据库字符集: ALTER DATABASE db_name DEFAULT CHARACTER SET character_name [COLLATE ...]; 把表默认的字符集和所有字符列( ...

  10. kafka server管理

    kafka启动以来zookeeper  kafka启动之前,首先要启动zookeeper 1.1.kafka启动单个节点 -daemon 表示程序以守护进程的方式后台云心 --override pro ...