zgq hace 5 años
padre
commit
728a8aadc0

+ 25 - 15
sys/src/main/java/com/rxida/xilinedu/sys/common/ShiroConfiguration.java

@@ -1,5 +1,6 @@
 package com.rxida.xilinedu.sys.common;
 
+import org.apache.shiro.authc.credential.HashedCredentialsMatcher;
 import org.apache.shiro.mgt.SecurityManager;
 import org.apache.shiro.spring.security.interceptor.AuthorizationAttributeSourceAdvisor;
 import org.apache.shiro.spring.web.ShiroFilterFactoryBean;
@@ -12,23 +13,9 @@ import java.util.Map;
 
 @Configuration
 public class ShiroConfiguration {
-    //将自己的验证方式加入容器
-    @Bean
-    public SystemAuthorizingRealm systemAuthorizingRealm() {
-        SystemAuthorizingRealm systemAuthorizingRealm = new SystemAuthorizingRealm();
-        return systemAuthorizingRealm;
-    }
-
-    //权限管理,配置主要是Realm的管理认证
-    @Bean
-    public SecurityManager securityManager() {
-        DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager();
-        securityManager.setRealm(systemAuthorizingRealm());
-        return securityManager;
-    }
 
     //Filter工厂,设置对应的过滤条件和跳转条件
-    @Bean
+    @Bean(name="shiroFilter")
     public ShiroFilterFactoryBean shiroFilterFactoryBean(SecurityManager securityManager) {
         ShiroFilterFactoryBean shiroFilterFactoryBean = new ShiroFilterFactoryBean();
         shiroFilterFactoryBean.setSecurityManager(securityManager);
@@ -47,6 +34,29 @@ public class ShiroConfiguration {
         return shiroFilterFactoryBean;
     }
 
+    //配置核心安全事务管理器
+    @Bean(name="securityManager")
+    public SecurityManager securityManager() {
+        DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager();
+        securityManager.setRealm(systemAuthorizingRealm());
+        return securityManager;
+    }
+
+    //将自己的验证方式加入容器
+    @Bean(name="systemAuthorizingRealm")
+    public SystemAuthorizingRealm systemAuthorizingRealm() {
+        SystemAuthorizingRealm systemAuthorizingRealm = new SystemAuthorizingRealm();
+        systemAuthorizingRealm.setCredentialsMatcher(hashedCredentialsMatcher());
+        return systemAuthorizingRealm;
+    }
+
+    @Bean
+    public HashedCredentialsMatcher hashedCredentialsMatcher(){
+        HashedCredentialsMatcher matcher = new HashedCredentialsMatcher("SHA-1");
+        matcher.setHashIterations(1024);
+        return matcher;
+    }
+
     //加入注解的使用,不加入这个注解不生效
     @Bean
     public AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor(SecurityManager securityManager) {

+ 15 - 52
sys/src/main/java/com/rxida/xilinedu/sys/common/SystemAuthorizingRealm.java

@@ -4,25 +4,29 @@ import com.rxida.xilinedu.sys.dao.UserDao;
 import com.rxida.xilinedu.sys.entity.Permission;
 import com.rxida.xilinedu.sys.entity.Role;
 import com.rxida.xilinedu.sys.entity.User;
+import com.rxida.xilinedu.sys.security.Digests;
 import com.rxida.xilinedu.sys.utils.Encodes;
-import org.apache.shiro.authc.AuthenticationException;
-import org.apache.shiro.authc.AuthenticationInfo;
-import org.apache.shiro.authc.AuthenticationToken;
-import org.apache.shiro.authc.SimpleAuthenticationInfo;
+import org.apache.shiro.authc.*;
 import org.apache.shiro.authz.AuthorizationInfo;
 import org.apache.shiro.authz.SimpleAuthorizationInfo;
 import org.apache.shiro.realm.AuthorizingRealm;
 import org.apache.shiro.subject.PrincipalCollection;
 import org.apache.shiro.util.ByteSource;
 import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
 
 import javax.annotation.Resource;
 import java.io.Serializable;
+import java.util.Arrays;
 
 public class SystemAuthorizingRealm extends AuthorizingRealm {
     @Autowired
     private UserDao userDao;
 
+    public SystemAuthorizingRealm() {
+        this.setCachingEnabled(false);
+    }
+
     //角色权限和对应权限添加
     @Override
     protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {
@@ -51,60 +55,19 @@ public class SystemAuthorizingRealm extends AuthorizingRealm {
             return null;
         }
         //获取用户信息
-        String username = authenticationToken.getPrincipal().toString();
+        String username = (String) authenticationToken.getPrincipal();
         User user = userDao.findByUsername(username);
         if (user == null) {
             //这里返回后会报出对应异常
             return null;
         } else {
-            byte[] salt = Encodes.decodeHex(user.getPassword().substring(0, 16));
-            //这里验证authenticationToken和simpleAuthenticationInfo的信息
-//            SimpleAuthenticationInfo simpleAuthenticationInfo = new SimpleAuthenticationInfo(username, salt, getName());
-            return new SimpleAuthenticationInfo(new Principal(user, false),
-                    user.getPassword().substring(16), ByteSource.Util.bytes(salt), getName());
-        }
-    }
-
-    /**
-     * 授权用户信息
-     */
-    public static class Principal implements Serializable {
 
-        private static final long serialVersionUID = 1L;
-
-        private String id; // 编号
-        private String loginName; // 登录名
-        private String name; // 姓名
-        private boolean mobileLogin; // 是否手机登录
-
-        public Principal(User user, boolean mobileLogin) {
-            this.id = user.getId();
-            this.loginName = user.getUsername();
-            this.name = user.getName();
-            this.mobileLogin = mobileLogin;
-        }
-
-        public String getId() {
-            return id;
-        }
-
-        public String getLoginName() {
-            return loginName;
-        }
-
-        public String getName() {
-            return name;
-        }
-
-        public boolean isMobileLogin() {
-            return mobileLogin;
-        }
-
-        @Override
-        public String toString() {
-            return id;
+            byte[] salt = Encodes.decodeHex(user.getPassword().substring(0, 16));
+            return new SimpleAuthenticationInfo(
+                    user,
+                    user.getPassword().substring(16),
+                    ByteSource.Util.bytes(salt),
+                    getName());
         }
-
     }
-
 }

+ 122 - 0
sys/src/main/java/com/rxida/xilinedu/sys/security/Digests.java

@@ -0,0 +1,122 @@
+/**
+ * Copyright (c) 2005-2012 springside.org.cn
+ */
+package com.rxida.xilinedu.sys.security;
+
+import com.rxida.xilinedu.sys.utils.Exceptions;
+import org.apache.commons.lang3.Validate;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.security.GeneralSecurityException;
+import java.security.MessageDigest;
+import java.security.SecureRandom;
+
+/**
+ * 支持SHA-1/MD5消息摘要的工具类.
+ * 
+ * 返回ByteSource,可进一步被编码为Hex, Base64或UrlSafeBase64
+ * 
+ * @author calvin
+ */
+public class Digests {
+
+	private static final String SHA1 = "SHA-1";
+	private static final String MD5 = "MD5";
+
+	private static SecureRandom random = new SecureRandom();
+
+	/**
+	 * 对输入字符串进行md5散列.
+	 */
+	public static byte[] md5(byte[] input) {
+		return digest(input, MD5, null, 1);
+	}
+	public static byte[] md5(byte[] input, int iterations) {
+		return digest(input, MD5, null, iterations);
+	}
+	
+	/**
+	 * 对输入字符串进行sha1散列.
+	 */
+	public static byte[] sha1(byte[] input) {
+		return digest(input, SHA1, null, 1);
+	}
+
+	public static byte[] sha1(byte[] input, byte[] salt) {
+		return digest(input, SHA1, salt, 1);
+	}
+
+	public static byte[] sha1(byte[] input, byte[] salt, int iterations) {
+		return digest(input, SHA1, salt, iterations);
+	}
+
+	/**
+	 * 对字符串进行散列, 支持md5与sha1算法.
+	 */
+	private static byte[] digest(byte[] input, String algorithm, byte[] salt, int iterations) {
+		try {
+			MessageDigest digest = MessageDigest.getInstance(algorithm);
+
+			if (salt != null) {
+				digest.update(salt);
+			}
+
+			byte[] result = digest.digest(input);
+
+			for (int i = 1; i < iterations; i++) {
+				digest.reset();
+				result = digest.digest(result);
+			}
+			return result;
+		} catch (GeneralSecurityException e) {
+			throw Exceptions.unchecked(e);
+		}
+	}
+
+	/**
+	 * 生成随机的Byte[]作为salt.
+	 * 
+	 * @param numBytes byte数组的大小
+	 */
+	public static byte[] generateSalt(int numBytes) {
+		Validate.isTrue(numBytes > 0, "numBytes argument must be a positive integer (1 or larger)", numBytes);
+
+		byte[] bytes = new byte[numBytes];
+		random.nextBytes(bytes);
+		return bytes;
+	}
+
+	/**
+	 * 对文件进行md5散列.
+	 */
+	public static byte[] md5(InputStream input) throws IOException {
+		return digest(input, MD5);
+	}
+
+	/**
+	 * 对文件进行sha1散列.
+	 */
+	public static byte[] sha1(InputStream input) throws IOException {
+		return digest(input, SHA1);
+	}
+
+	private static byte[] digest(InputStream input, String algorithm) throws IOException {
+		try {
+			MessageDigest messageDigest = MessageDigest.getInstance(algorithm);
+			int bufferLength = 8 * 1024;
+			byte[] buffer = new byte[bufferLength];
+			int read = input.read(buffer, 0, bufferLength);
+
+			while (read > -1) {
+				messageDigest.update(buffer, 0, read);
+				read = input.read(buffer, 0, bufferLength);
+			}
+
+			return messageDigest.digest();
+		} catch (GeneralSecurityException e) {
+			throw Exceptions.unchecked(e);
+		}
+	}
+	
+}

+ 2 - 1
sys/src/main/java/com/rxida/xilinedu/sys/web/LoginController.java

@@ -27,11 +27,12 @@ public class LoginController {
         try {
             subject.login(usernamePasswordToken);
             resultData.put("token", usernamePasswordToken.toString());
+            result.setMsg("success!!!");
             result.setCode(JsonResult.SUCCESS);
         } catch (UnknownAccountException uae) {
             resultData.put("token", usernamePasswordToken.toString());
             result.setCode(JsonResult.ERROE);
-            result.setMsg("账号不存在");
+            result.setMsg("用户不存在");
         } catch (IncorrectCredentialsException ice) {
             resultData.put("token", usernamePasswordToken.toString());
             result.setCode(JsonResult.ERROE);