zoukankan      html  css  js  c++  java
  • Spring security实现国际化问题

    这两天Spring用户登录国际化这个问题困扰我好久啊,于昨天晚上终于把它干掉了。

    场景就是我们公司的产品-incopat,需要支持中英文,用户登录这块用的spring自带的security,需求讲的通俗一点就是,中文版提示中文提示信息,英文版提示英文版信息,废话不多说,见代码。

    首先配置文件

    security-config.xml

     1 <beans:bean id="customUsernamePasswordAuthenticationFilter"
     2         class="com.incoshare.base.security.CustomUsernamePasswordAuthenticationFilter"
     3         p:authenticationManager-ref="authenticationManager"
     4         p:filterProcessesUrl="/doLogin" p:sessionAuthenticationStrategy-ref="compositeSessionAuthenticationStrategy"
     5         p:authenticationSuccessHandler-ref="authenticationSuccessHandler"
     6         p:authenticationFailureHandler-ref="authenticationFailureHandler"
     7         p:rememberMeServices-ref="rememberMeServices"
     8         p:authenticationDetailsSource-ref="customWebAuthenticationDetailsSource">
     9 </beans:bean>
    10 
    11 
    12 <beans:bean id="messageSource"
    13         class="org.springframework.context.support.ReloadableResourceBundleMessageSource">
    14         <beans:property name="basename"
    15             value="classpath:messages/security/messages" />
    16 </beans:bean>

    配置文件只贴了关键部分,第一个bean 配置登录的过滤器,第二个bean加载messages文件(这里有需要注意的地方如果想引用自己的message文件,建好文件后提供相对地址就可以了,classpath必须要哦!文件命名也是有规则的,message_en  就是下划线带上语言简称,这个简称需要跟网站上切换中英文标示一致),配置文件就这些

    下面贴上过滤器代码

      1 package com.incoshare.base.security;
      2 
      3 import javax.servlet.http.HttpServletRequest;
      4 import javax.servlet.http.HttpServletResponse;
      5 
      6 import com.incoshare.base.util.PropertyUtil;
      7 import com.incoshare.base.util.Utils;
      8 import com.incoshare.incopat4.model.User;
      9 import com.incoshare.incopat4.service.usermanager.UserListService;
     10 import com.incoshare.util.EncryptUtils;
     11 import com.incoshare.util.SingleLoginUtils;
     12 import org.slf4j.Logger;
     13 import org.slf4j.LoggerFactory;
     14 
     15 import org.springframework.beans.factory.annotation.Autowired;
     16 import org.springframework.beans.factory.annotation.Value;
     17 import org.springframework.context.i18n.LocaleContextHolder;
     18 import org.springframework.security.authentication.AuthenticationServiceException;
     19 import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
     20 import org.springframework.security.core.Authentication;
     21 import org.springframework.security.core.AuthenticationException;
     22 import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;
     23 import org.springframework.util.StringUtils;
     24 import org.springframework.web.servlet.i18n.SessionLocaleResolver;
     25 import org.springframework.web.util.WebUtils;
     26 
     27 import com.incoshare.base.util.RegexUtil;
     28 
     29 import java.text.SimpleDateFormat;
     30 import java.util.Date;
     31 import java.util.Locale;
     32 
     33 public class CustomUsernamePasswordAuthenticationFilter extends UsernamePasswordAuthenticationFilter{
     34     
     35     static Logger logger = LoggerFactory
     36             .getLogger(CustomUsernamePasswordAuthenticationFilter.class);
     37 
     38     private boolean postOnly = true;
     39 
     40     private byte[] keyBytes = { 0x21, 0x12, 0x4F, 0x58, (byte) 0x88, 0x09, 0x40, 0x38, 0x74,
     41             0x25, (byte) 0x99, 0x21, (byte) 0xCB, (byte) 0xDD, 0x58, 0x66, 0x77, 0x22, 0x74,
     42             (byte) 0x98, 0x30, 0x40, 0x36, (byte) 0xE2 };
     43     private byte[] keyBytesForSjz = { 0x22, 0x12, 0x4F, 0x58, (byte) 0x88, 0x09, 0x40, 0x38, 0x74,
     44             0x25, (byte) 0x99, 0x21, (byte) 0xCB, (byte) 0xDD, 0x48, 0x66, 0x77, 0x22, 0x74,
     45             (byte) 0x98, 0x30, 0x40, 0x36, (byte) 0xE2 };
     46     @Autowired
     47     UserListService userListService;
     48     @Autowired
     49     PropertyUtil propertyUtil;
     50 
     51     @Override
     52      public Authentication attemptAuthentication(HttpServletRequest request, HttpServletResponse response) throws AuthenticationException {
     53         
     54             
     55         String newLocale = request.getParameter("locallangue");
     56         if (newLocale != null) {
     57             Locale locale = StringUtils.parseLocaleString(newLocale);
     58             WebUtils.setSessionAttribute(request,
     59                 SessionLocaleResolver.LOCALE_SESSION_ATTRIBUTE_NAME, locale);
     60             LocaleContextHolder.setLocale(locale, true);
     61         }
    //这块代码就是通过获取前台返回的语言编码,设置到spring的localeContextHolder里
    62 if (postOnly && !request.getMethod().equals("POST")) { 63 throw new AuthenticationServiceException("Authentication method not supported: " + request.getMethod()); 64 } 65 66 String username = obtainUsername(request); 67 String password = obtainPassword(request); 68 69 //集慧智佳用户登录 70 String token = request.getParameter("token"); 71 //石家庄单点登录 72 String tokenForSjz = request.getParameter("tokenForSjz"); 73 if(Utils.isNotNull(token) || Utils.isNotNull(tokenForSjz)){ 74 boolean judge = true; 75 if(Utils.isNull(token)){ 76 judge = false; 77 } 78 SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH"); 79 Date date = new Date(); 80 String dateStr = simpleDateFormat.format(date); 81 String decodeToken = ""; 82 String decryptJudge = ""; 83 if(judge){ 84 decodeToken = EncryptUtils.DataDecrypt(keyBytes, token); 85 decryptJudge = token; 86 }else{ 87 decodeToken = EncryptUtils.DataDecrypt(keyBytesForSjz, tokenForSjz); 88 decryptJudge = tokenForSjz; 89 }; 90 if(!decodeToken.equals(decryptJudge.trim()) && decodeToken.equals(dateStr.trim())){ 91 92 User user = userListService.queryUserJhzj(username); 93 if(Utils.isNotNull(user)){ 94 if(Utils.isNotNull(user.getOrganizationId())){ 95 if(judge){ 96 String jhzjOrid=propertyUtil.getContextProperty("jhzjOrid"); 97 String pwd = propertyUtil.getContextProperty("jhzjPassword").trim(); 98 if(user.getOrganizationId().equals(Integer.parseInt(jhzjOrid.trim()))){ 99 password = pwd; 100 } 101 }else{ 102 if(Utils.isNotNull(password)){ 103 String record = password; 104 String orid = propertyUtil.getContextProperty("sjzOrid").trim(); 105 password = EncryptUtils.DataDecrypt(keyBytesForSjz,password); 106 if(record.equals(password) || !String.valueOf(user.getOrganizationId()).equals(orid)){ 107 password = ""; 108 } 109 } 110 } 111 112 } 113 } 114 115 }else{ 116 password = ""; 117 } 118 } 119 120 String tokenForLogin = request.getParameter("tokenForLogin"); 121 if(Utils.isNotNull(tokenForLogin)){ 122 String companyName = request.getParameter("companyName"); 123 String record = password; 124 tokenForLogin = tokenForLogin.replaceAll(" ","+"); 125 password = SingleLoginUtils.decryptPassword(username,password,tokenForLogin,companyName,userListService,propertyUtil,logger); 126 if(Utils.isNull(password)){ 127 logger.info("{}:密码解密为空。账号{},没有解密的密码:{}",companyName,username,record); 128 } 129 } 130 if (username == null) { 131 username = ""; 132 } 133 134 if (password == null) { 135 password = ""; 136 } 137 138 139 username = username.trim(); 140 141 UsernamePasswordAuthenticationToken authRequest = new UsernamePasswordAuthenticationToken(username, password); 142 143 if(!StringUtils.isEmpty(request.getParameter("iplogin"))) { 144 username = RegexUtil.getRealIp(request); 145 password=""; 146 authRequest = new IpUserAuthenticationToken(username,password); 147 } 148 149 this.logger.info("user:{},ip:{} trying to login",new Object[]{username,RegexUtil.getRealIp(request)}); 150 151 // Allow subclasses to set the "details" property 152 setDetails(request, authRequest); 153 154 return this.getAuthenticationManager().authenticate(authRequest); 155 } 156 }

    这块先声明下,代码不是我写的,看着很乱很糟糕吧。主要上边标黄的两个地方就可以了。

    值设置后会通过this.getAuthenticationManager().authenticate(authRequest) 去初始化,喜欢研究源码的朋友看一跟一下看看

    org.springframework.context.i18n.LocaleContextHolder这个类

    1 public static LocaleContext getLocaleContext() {
    2         LocaleContext localeContext = localeContextHolder.get();
    3         if (localeContext == null) {
    4             localeContext = inheritableLocaleContextHolder.get();//这里会把你设置的值放到Spring 容器
    5         }
    6         return localeContext;
    7 }

    好了,关键的地方都说完了,这几天搞了这么久,写完了也没多少东西,代码就是这么美妙,解决问题的过程是漫长苦恼的,但最终解决有可能就一两行代码的事。

    关于这一块有问题的可以随时沟通。

  • 相关阅读:
    使用Flex Bison 和LLVM编写自己的编译器[zz]
    应用开发框架讨论应用配置wxFileConfig
    交流电220V是从何而来的
    电压、电流、电阻的概念
    电路返回端,接地,大地,等势体,静电场,回路,电能
    泛型实现List(List<T>)排序
    javascript注册功能
    层(div或table)的左右滚动
    javascript正则表达式检验
    JavaScript通用类库(ZT)
  • 原文地址:https://www.cnblogs.com/boboxing/p/9603604.html
Copyright © 2011-2022 走看看