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) 注:以下内 ...
随机推荐
- 安装 composer 并启动 yii2 项目
环境 MacOS 10.12.6 PHP 5.6.30 yii2.0 一.composer (类似 node's npm) 1.安装 php -r "copy('https://getcom ...
- docker配置仓储库时出错:无法安全地用该源进行更新,所以默认禁用该源
在Ubuntu上安装docker,配置仓储库时第一次使用了阿里去的镜像,如下 sudo add-apt-repository "deb [arch=amd64] http://mirrors ...
- 脚手架vue-cli系列一:安装与规范
我很喜欢Vue的一个重要原因就是因为它的vue-cli,这个工具可以让一个简单的命令行工具来帮助我快速地构建一个足以支撑实际项目开发的Vue环境,并不像Angular和React那样要在Yoman上找 ...
- 自动化测试框架的Step By Step搭建及测试实战(1)
1.1什么是自动化测试框架 1.什么是自动化框架 自动化框架是应用与自动化测试的程序框架,它提供了可重用的自动化测试模块,提供最基础的自动化测试功能,或提供自动化测试执行和管理功能的架构模块.它是由一 ...
- SpringBoot之OAuth2.0学习之客户端快速上手
2.1.@EnableOAuth2Sso 这个注解是为了开启OAuth2.0的sso功能,如果我们配置了WebSecurityConfigurerAdapter,它通过添加身份验证过滤器和身份验证(e ...
- Spring Boot + Spring Cloud 实现权限管理系统 后端篇(二十五):Spring Security 版本
在线演示 演示地址:http://139.196.87.48:9002/kitty 用户名:admin 密码:admin 技术背景 到目前为止,我们使用的权限认证框架是 Shiro,虽然 Shiro ...
- Linux 定时任务 crontab 和 Systemd Timer
一.说说八卦 说到定时任务,我们常用的就是 crond 服务,但是我们不知道还有另外一种定时方式,那就是 systemd,我们常用 systemd 来管理我们的服务,但是我们却不知道,我们还可以通 ...
- zookeeper ZAB协议 Follower和leader源码分析
Follower处理逻辑 void followLeader() throws InterruptedException { //... try { //获取leader server QuorumS ...
- 通过 URL 打开 Activity
为每个 Activity 绑定一个 url 可以方便的让第三方 app 直接打开这些 Activity.也可以方便在 app 内部进行页面跳转,解耦. 背景 举一个常见的案例,假设我们有个产品 A,产 ...
- Qt使用正则表达式去掉小数位多余的0
QRegExp rx; rx.setPattern("(\\.){0,1}0+$"); double double01 = 15648.120000; double double0 ...