Explorar o código

添加用户token规则

温红权 %!s(int64=9) %!d(string=hai) anos
pai
achega
1d41b67c51
Modificáronse 19 ficheiros con 664 adicións e 388 borrados
  1. 90 83
      VisualInspection_server/pom.xml
  2. 3 1
      VisualInspection_server/src/main/java/com/xintong/visualinspection/VideocheckApplication.java
  3. 44 19
      VisualInspection_server/src/main/java/com/xintong/visualinspection/bean/User.java
  4. 42 4
      VisualInspection_server/src/main/java/com/xintong/visualinspection/controller/UserController.java
  5. 17 0
      VisualInspection_server/src/main/java/com/xintong/visualinspection/pojo/JwtAuthenticationResponse.java
  6. 70 0
      VisualInspection_server/src/main/java/com/xintong/visualinspection/pojo/SimpleGrantedAuthority.java
  7. 82 0
      VisualInspection_server/src/main/java/com/xintong/visualinspection/securityTools/JwtAuthenticationTokenFilter.java
  8. 134 0
      VisualInspection_server/src/main/java/com/xintong/visualinspection/securityTools/JwtTokenUtil.java
  9. 0 53
      VisualInspection_server/src/main/java/com/xintong/visualinspection/securityTools/MyAccessDecisionManager.java
  10. 0 77
      VisualInspection_server/src/main/java/com/xintong/visualinspection/securityTools/MyFilterSecurityInterceptor.java
  11. 0 40
      VisualInspection_server/src/main/java/com/xintong/visualinspection/securityTools/MyGrantedAuthority.java
  12. 0 76
      VisualInspection_server/src/main/java/com/xintong/visualinspection/securityTools/MyInvocationSecurityMetadataSourceService.java
  13. 27 0
      VisualInspection_server/src/main/java/com/xintong/visualinspection/securityTools/RedisCacheUtil.java
  14. 2 0
      VisualInspection_server/src/main/java/com/xintong/visualinspection/securityTools/RedisConf.java
  15. 41 18
      VisualInspection_server/src/main/java/com/xintong/visualinspection/securityTools/WebSecurityConfig.java
  16. 8 0
      VisualInspection_server/src/main/java/com/xintong/visualinspection/service/AuthService.java
  17. 81 0
      VisualInspection_server/src/main/java/com/xintong/visualinspection/service/impl/AuthServiceImpl.java
  18. 11 10
      VisualInspection_server/src/main/java/com/xintong/visualinspection/service/impl/UserServiceImpl.java
  19. 12 7
      VisualInspection_server/src/main/resources/application.properties

+ 90 - 83
VisualInspection_server/pom.xml

@@ -17,7 +17,7 @@
 		<groupId>org.springframework.boot</groupId>
 		<artifactId>spring-boot-starter-parent</artifactId>
 		<version>1.5.2.RELEASE</version>
-		<relativePath/> <!-- lookup parent from repository -->
+		<relativePath /> <!-- lookup parent from repository -->
 	</parent>
 
 	<properties>
@@ -43,75 +43,82 @@
 			<version>1.2.0</version>
 		</dependency>
 
-        <dependency>
-            <groupId>org.springframework.boot</groupId>
-            <artifactId>spring-boot-starter-thymeleaf</artifactId>
-        </dependency>
+		<dependency>
+			<groupId>org.springframework.boot</groupId>
+			<artifactId>spring-boot-starter-thymeleaf</artifactId>
+		</dependency>
 
-        <dependency>
-            <groupId>org.springframework.boot</groupId>
-            <artifactId>spring-boot-starter-remote-shell</artifactId>
-        </dependency>
+		<dependency>
+			<groupId>org.springframework.boot</groupId>
+			<artifactId>spring-boot-starter-remote-shell</artifactId>
+		</dependency>
 
-        <dependency>
-            <groupId>org.springframework.boot</groupId>
-            <artifactId>spring-boot-starter-data-redis</artifactId>
-        </dependency>
+		<dependency>
+			<groupId>org.springframework.boot</groupId>
+			<artifactId>spring-boot-starter-data-redis</artifactId>
+		</dependency>
 
 
-        <dependency>
+		<dependency>
 			<groupId>org.springframework.boot</groupId>
 			<artifactId>spring-boot-devtools</artifactId>
 		</dependency>
 
 
-        <!--<dependency>-->
-            <!--<groupId>org.springframework.session</groupId>-->
-            <!--<artifactId>spring-session-data-redis</artifactId>-->
-        <!--</dependency>-->
+		<dependency>
+			<groupId>io.jsonwebtoken</groupId>
+			<artifactId>jjwt</artifactId>
+			<version>0.7.0</version>
+		</dependency>
 
 
+		<!--<dependency> -->
+		<!--<groupId>org.springframework.session</groupId> -->
+		<!--<artifactId>spring-session-data-redis</artifactId> -->
+		<!--</dependency> -->
 
-        <!--<dependency>-->
-            <!--<groupId>redis.clients</groupId>-->
-            <!--<artifactId>jedis</artifactId>-->
-            <!--<version>2.9.0</version>-->
-        <!--</dependency>-->
 
 
-        <!--<dependency>-->
-            <!--<groupId>org.springframework.boot</groupId>-->
-            <!--<artifactId>spring-boot-starter-data-jpa</artifactId>-->
-        <!--</dependency>-->
+		<!--<dependency> -->
+		<!--<groupId>redis.clients</groupId> -->
+		<!--<artifactId>jedis</artifactId> -->
+		<!--<version>2.9.0</version> -->
+		<!--</dependency> -->
 
-        <!-- http://mvnrepository.com/artifact/org.thymeleaf.extras/thymeleaf-extras-springsecurity4 -->
-        <dependency>
-            <groupId>org.thymeleaf.extras</groupId>
-            <artifactId>thymeleaf-extras-springsecurity4</artifactId>
-            <version>2.1.2.RELEASE</version>
-        </dependency>
 
-        <!-- https://mvnrepository.com/artifact/org.thymeleaf/thymeleaf-spring4 -->
-        <!--<dependency>-->
-            <!--<groupId>org.thymeleaf</groupId>-->
-            <!--<artifactId>thymeleaf-spring4</artifactId>-->
-            <!--<version>3.0.5.RELEASE</version>-->
-        <!--</dependency>-->
+		<!--<dependency> -->
+		<!--<groupId>org.springframework.boot</groupId> -->
+		<!--<artifactId>spring-boot-starter-data-jpa</artifactId> -->
+		<!--</dependency> -->
 
+		<!-- http://mvnrepository.com/artifact/org.thymeleaf.extras/thymeleaf-extras-springsecurity4 -->
+		<dependency>
+			<groupId>org.thymeleaf.extras</groupId>
+			<artifactId>thymeleaf-extras-springsecurity4</artifactId>
+			<version>2.1.2.RELEASE</version>
+		</dependency>
 
+		<!-- https://mvnrepository.com/artifact/org.thymeleaf/thymeleaf-spring4 -->
+		<!--<dependency> -->
+		<!--<groupId>org.thymeleaf</groupId> -->
+		<!--<artifactId>thymeleaf-spring4</artifactId> -->
+		<!--<version>3.0.5.RELEASE</version> -->
+		<!--</dependency> -->
 
-        <!--<dependency>-->
-            <!--<groupId>org.springframework.security</groupId>-->
-            <!--<artifactId>spring-security-taglibs</artifactId>-->
-            <!--<version>4.2.1.RELEASE</version>-->
-        <!--</dependency>-->
 
 
-        <dependency>
-            <groupId>com.github.pagehelper</groupId>
-            <artifactId>pagehelper</artifactId>
-            <version>4.2.1</version>
-        </dependency>
+		<!--<dependency> -->
+		<!--<groupId>org.springframework.security</groupId> -->
+		<!--<artifactId>spring-security-taglibs</artifactId> -->
+		<!--<version>4.2.1.RELEASE</version> -->
+		<!--</dependency> -->
+
+
+		<dependency>
+			<groupId>com.github.pagehelper</groupId>
+			<artifactId>pagehelper</artifactId>
+			<version>4.2.1</version>
+		</dependency>
 
 
 		<dependency>
@@ -126,28 +133,28 @@
 			<version>5.1.41</version>
 		</dependency>
 
-        <dependency>
-            <groupId>com.alibaba</groupId>
-            <artifactId>druid</artifactId>
-            <version>1.0.29</version>
-        </dependency>
+		<dependency>
+			<groupId>com.alibaba</groupId>
+			<artifactId>druid</artifactId>
+			<version>1.0.29</version>
+		</dependency>
 
-        <dependency>
-            <groupId>com.alibaba</groupId>
-            <artifactId>fastjson</artifactId>
-            <version>1.2.31</version>
-        </dependency>
+		<dependency>
+			<groupId>com.alibaba</groupId>
+			<artifactId>fastjson</artifactId>
+			<version>1.2.31</version>
+		</dependency>
 
 
 
-        <dependency>
+		<dependency>
 			<groupId>org.springframework.boot</groupId>
 			<artifactId>spring-boot-starter-test</artifactId>
 			<scope>test</scope>
 		</dependency>
 
 
-    </dependencies>
+	</dependencies>
 
 	<dependencyManagement>
 		<dependencies>
@@ -192,14 +199,14 @@
 					<exclude>**/application*.properties</exclude>
 				</excludes>
 			</resource>
-            <resource>
-                <directory>src/main/java</directory>
-                <includes>
-                    <include>**/*.properties</include>
-                    <include>**/*.xml</include>
-                </includes>
-                <filtering>false</filtering>
-            </resource>
+			<resource>
+				<directory>src/main/java</directory>
+				<includes>
+					<include>**/*.properties</include>
+					<include>**/*.xml</include>
+				</includes>
+				<filtering>false</filtering>
+			</resource>
 			<resource>
 				<directory>src/main/resources</directory>
 				<targetPath>BOOT-INF/lib/</targetPath>
@@ -217,20 +224,20 @@
 		</resources>
 	</build>
 
-  <repositories>
-        <repository>
-            <id>spring-releases</id>
-            <name>Spring Releases</name>
-            <url>https://repo.spring.io/libs-release</url>
-        </repository>
-    </repositories>
-    <pluginRepositories>
-        <pluginRepository>
-            <id>spring-releases</id>
-            <name>Spring Releases</name>
-            <url>https://repo.spring.io/libs-release</url>
-        </pluginRepository>
-    </pluginRepositories>
+	<repositories>
+		<repository>
+			<id>spring-releases</id>
+			<name>Spring Releases</name>
+			<url>https://repo.spring.io/libs-release</url>
+		</repository>
+	</repositories>
+	<pluginRepositories>
+		<pluginRepository>
+			<id>spring-releases</id>
+			<name>Spring Releases</name>
+			<url>https://repo.spring.io/libs-release</url>
+		</pluginRepository>
+	</pluginRepositories>
 
 
 </project>

+ 3 - 1
VisualInspection_server/src/main/java/com/xintong/visualinspection/VideocheckApplication.java

@@ -26,7 +26,9 @@ public class VideocheckApplication {
 
 
 	public static void main(String[] args) {
-        ParserConfig.getGlobalInstance().addAccept("com.xintong.visualinspection.bean");
+		ParserConfig.getGlobalInstance().addAccept("com.xintong.visualinspection.");
+		ParserConfig.getGlobalInstance().addAccept("org.springframework.security.core.");
+        
         SpringApplication.run(VideocheckApplication.class, args);
 	}
 }

+ 44 - 19
VisualInspection_server/src/main/java/com/xintong/visualinspection/bean/User.java

@@ -22,7 +22,6 @@ public class User implements UserDetails {
 	// 姓名
 	private String truename;
 	// 密码
-	@JsonIgnore
 	private String password;
 	// 组织机构ID
 	private int organid;
@@ -68,45 +67,70 @@ public class User implements UserDetails {
 	private int workno;
 	// 身份证号
 	private String idno;
+	
+	private String token;
 
 	@JsonIgnore
 	private List<Role> roles;
 	private List<? extends GrantedAuthority> authorities;
 
-	public User() {
 
+	public User() {
+       super();
 	}
 
 	public User(String username, String password, List<GrantedAuthority> grantedAuthorities) {
+		super();
 		this.username = username;
 		this.password = password;
 		this.authorities = grantedAuthorities;
 	}
 
 	@JsonIgnore
-	@Override
-	public boolean isAccountNonExpired() {
-		return true;
-	}
-
-	@JsonIgnore
-	@Override
-	public boolean isAccountNonLocked() {
-		return true;
+	public Integer getId() {
+		return id;
 	}
 
-	@JsonIgnore
-	@Override
-	public boolean isCredentialsNonExpired() {
-		return true;
-	}
+//	@JsonIgnore
+//	@Override
+//	public String getPassword() {
+//		return password;
+//	}
 
-	@JsonIgnore
 	@Override
-	public boolean isEnabled() {
-		return true;
+	public String getUsername() {
+		return username;
 	}
 
+	 // 账户是否未过期
+    @JsonIgnore
+    @Override
+    public boolean isAccountNonExpired() {
+        return true;
+    }
+
+    // 账户是否未锁定
+    @JsonIgnore
+    @Override
+    public boolean isAccountNonLocked() {
+        return true;
+    }
+    
+    // 密码是否未过期
+    @JsonIgnore
+    @Override
+    public boolean isCredentialsNonExpired() {
+        return true;
+    }
+
+    // 账户是否激活
+    @JsonIgnore
+    @Override
+    public boolean isEnabled() {
+        return true;
+    }
+
+	// 返回分配给用户的角色列表
 	@JsonIgnore
 	@Override
 	public Collection<? extends GrantedAuthority> getAuthorities() {
@@ -116,5 +140,6 @@ public class User implements UserDetails {
 	public void setGrantedAuthorities(List<? extends GrantedAuthority> authorities) {
 		this.authorities = authorities;
 	}
+	
 
 }

+ 42 - 4
VisualInspection_server/src/main/java/com/xintong/visualinspection/controller/UserController.java

@@ -1,13 +1,26 @@
 package com.xintong.visualinspection.controller;
 
+import javax.servlet.http.HttpServletRequest;
+
 import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.http.ResponseEntity;
+import org.springframework.security.access.prepost.PreAuthorize;
+import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
 import org.springframework.security.authentication.encoding.Md5PasswordEncoder;
+import org.springframework.security.core.Authentication;
+import org.springframework.security.core.AuthenticationException;
+import org.springframework.security.core.context.SecurityContextHolder;
+import org.springframework.security.core.userdetails.UserDetails;
 import org.springframework.web.bind.annotation.RequestBody;
 import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RequestMethod;
 import org.springframework.web.bind.annotation.RestController;
 
 import com.alibaba.fastjson.JSON;
 import com.xintong.visualinspection.bean.User;
+import com.xintong.visualinspection.pojo.JwtAuthenticationResponse;
+import com.xintong.visualinspection.service.AuthService;
 import com.xintong.visualinspection.service.UserService;
 
 /**
@@ -20,11 +33,17 @@ public class UserController extends BaseController {
 
     @Autowired
     private UserService userService;
+    
+    @Autowired
+    private AuthService authService;
+    
+    @Value("${jwt.header}")
+    private String tokenHeader;
 
-    @RequestMapping(value = "/test")
-    public String test(){
-        User u = userService.getOne((long) 1);
-        return JSON.toJSON(u).toString();
+    @RequestMapping(value = "/auth/login",method=RequestMethod.POST)
+    public User login(@RequestBody User user){
+    	User u = authService.login(user.getUsername(), user.getPassword());
+        return u;
     }
     /**
      * 添加用户
@@ -33,6 +52,7 @@ public class UserController extends BaseController {
      * @exception
      * @since  1.0.0
      */
+    @PreAuthorize("hasRole('ADMIN')")
     @RequestMapping(value = "/addUser")
     public String addUser(@RequestBody User user) throws Exception{
     	user.setPassword(new Md5PasswordEncoder().encodePassword(user.getPassword(), null));
@@ -73,4 +93,22 @@ public class UserController extends BaseController {
         	return super.returnResult(-1, "删除失败", null);
         }
     }
+    
+    
+
+        @RequestMapping(value = "/refresh", method = RequestMethod.GET)
+        public ResponseEntity<?> refreshAndGetAuthenticationToken(
+                HttpServletRequest request) throws AuthenticationException{
+            String token = request.getHeader(tokenHeader);
+            String refreshedToken = authService.refresh(token);
+            if(refreshedToken == null) {
+                return ResponseEntity.badRequest().body(null);
+            } else {
+                return ResponseEntity.ok(new JwtAuthenticationResponse(refreshedToken));
+            }
+        }
+
+    
+    
+    
 }

+ 17 - 0
VisualInspection_server/src/main/java/com/xintong/visualinspection/pojo/JwtAuthenticationResponse.java

@@ -0,0 +1,17 @@
+package com.xintong.visualinspection.pojo;
+
+import java.io.Serializable;
+
+public class JwtAuthenticationResponse implements Serializable {
+    private static final long serialVersionUID = 1250166508152483573L;
+
+    private final String token;
+
+    public JwtAuthenticationResponse(String token) {
+        this.token = token;
+    }
+
+    public String getToken() {
+        return this.token;
+    }
+}

+ 70 - 0
VisualInspection_server/src/main/java/com/xintong/visualinspection/pojo/SimpleGrantedAuthority.java

@@ -0,0 +1,70 @@
+package com.xintong.visualinspection.pojo;
+
+/*
+ * Copyright 2002-2016 the original author or authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import org.springframework.security.core.GrantedAuthority;
+import org.springframework.security.core.SpringSecurityCoreVersion;
+import org.springframework.util.Assert;
+
+/**
+ * Basic concrete implementation of a {@link GrantedAuthority}.
+ *
+ * <p>
+ * Stores a {@code String} representation of an authority granted to the
+ * {@link org.springframework.security.core.Authentication Authentication} object.
+ *
+ * @author Luke Taylor
+ */
+public  class SimpleGrantedAuthority implements GrantedAuthority {
+
+	private static final long serialVersionUID = SpringSecurityCoreVersion.SERIAL_VERSION_UID;
+
+	private  String role;
+	
+	public SimpleGrantedAuthority(){
+		
+	}
+
+	public SimpleGrantedAuthority(String role) {
+		Assert.hasText(role, "A granted authority textual representation is required");
+		this.role = role;
+	}
+
+	public String getAuthority() {
+		return role;
+	}
+
+	public boolean equals(Object obj) {
+		if (this == obj) {
+			return true;
+		}
+
+		if (obj instanceof SimpleGrantedAuthority) {
+			return role.equals(((SimpleGrantedAuthority) obj).role);
+		}
+
+		return false;
+	}
+
+	public int hashCode() {
+		return this.role.hashCode();
+	}
+
+	public String toString() {
+		return this.role;
+	}
+}

+ 82 - 0
VisualInspection_server/src/main/java/com/xintong/visualinspection/securityTools/JwtAuthenticationTokenFilter.java

@@ -0,0 +1,82 @@
+package com.xintong.visualinspection.securityTools;
+
+import java.io.IOException;
+import java.util.concurrent.TimeUnit;
+
+import javax.servlet.FilterChain;
+import javax.servlet.ServletException;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.data.redis.core.RedisTemplate;
+import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
+import org.springframework.security.core.context.SecurityContextHolder;
+import org.springframework.security.core.userdetails.UserDetails;
+import org.springframework.security.core.userdetails.UserDetailsService;
+import org.springframework.security.web.authentication.WebAuthenticationDetailsSource;
+import org.springframework.stereotype.Component;
+import org.springframework.web.filter.OncePerRequestFilter;
+
+import com.xintong.visualinspection.bean.User;
+
+@Component
+public class JwtAuthenticationTokenFilter extends OncePerRequestFilter {
+
+	@Autowired
+	private UserDetailsService userDetailsService;
+
+	@Autowired
+	private JwtTokenUtil jwtTokenUtil;
+	
+	@Autowired
+	private RedisCacheUtil redisCacheUtil;
+	
+
+	@Value("${jwt.header}")
+	private String tokenHeader;
+	
+	@Value("${jwt.expiration}")
+	private int expiration;
+	
+
+	@Value("${jwt.tokenHead}")
+	private String tokenHead;
+
+	@Override
+	protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain chain)
+			throws ServletException, IOException {
+		String authHeader = request.getHeader(this.tokenHeader);
+		if (authHeader != null && authHeader.startsWith(tokenHead)) {
+			final String authToken = authHeader.substring(tokenHead.length()); // The  part after "XingTong "
+			String username = jwtTokenUtil.getUsernameFromToken(authToken);
+
+			logger.info("checking authentication " + username);
+
+			if (username != null && SecurityContextHolder.getContext().getAuthentication() == null) {
+
+				UserDetails u = redisCacheUtil.getUserByUserName(username);
+				// 验证是否跟缓存中有无
+				if (u != null) {
+					UserDetails userDetails = this.userDetailsService.loadUserByUsername(username);
+
+					User u_t = (User) u;
+					
+	                //判定token中的用户名是否数据库中一致 是与缓存中的用户token一致
+					if (jwtTokenUtil.validateToken(authToken, userDetails)&& authToken.equals(u_t.getToken())) {
+						
+						redisCacheUtil.setUser(username, u, expiration);
+						UsernamePasswordAuthenticationToken authentication = new UsernamePasswordAuthenticationToken(
+								userDetails, null, userDetails.getAuthorities());
+						authentication.setDetails(new WebAuthenticationDetailsSource().buildDetails(request));
+						logger.info("authenticated user " + username + ", setting security context");
+						SecurityContextHolder.getContext().setAuthentication(authentication);
+					}
+				}
+			}
+		}
+
+		chain.doFilter(request, response);
+	}
+}

+ 134 - 0
VisualInspection_server/src/main/java/com/xintong/visualinspection/securityTools/JwtTokenUtil.java

@@ -0,0 +1,134 @@
+package com.xintong.visualinspection.securityTools;
+
+import io.jsonwebtoken.Claims;
+import io.jsonwebtoken.Jwts;
+import io.jsonwebtoken.SignatureAlgorithm;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.security.core.userdetails.UserDetails;
+import org.springframework.stereotype.Component;
+
+import com.xintong.visualinspection.bean.User;
+
+import java.io.Serializable;
+import java.util.Date;
+import java.util.HashMap;
+import java.util.Map;
+
+@Component
+public class JwtTokenUtil implements Serializable {
+
+    private static final long serialVersionUID = -3301605591108950415L;
+
+    private static final String CLAIM_KEY_USERNAME = "sub";
+    private static final String CLAIM_KEY_CREATED = "created";
+
+    @Value("${jwt.secret}")
+    private String secret;
+
+    @Value("${jwt.expiration}")
+    private Long expiration;
+
+    public String getUsernameFromToken(String token) {
+        String username;
+        try {
+            final Claims claims = getClaimsFromToken(token);
+            username = claims.getSubject();
+        } catch (Exception e) {
+            username = null;
+        }
+        return username;
+    }
+
+    public Date getCreatedDateFromToken(String token) {
+        Date created;
+        try {
+            final Claims claims = getClaimsFromToken(token);
+            created = new Date((Long) claims.get(CLAIM_KEY_CREATED));
+        } catch (Exception e) {
+            created = null;
+        }
+        return created;
+    }
+
+    public Date getExpirationDateFromToken(String token) {
+        Date expiration;
+        try {
+            final Claims claims = getClaimsFromToken(token);
+            expiration = claims.getExpiration();
+        } catch (Exception e) {
+            expiration = null;
+        }
+        return expiration;
+    }
+
+    private Claims getClaimsFromToken(String token) {
+        Claims claims;
+        try {
+            claims = Jwts.parser()
+                    .setSigningKey(secret)
+                    .parseClaimsJws(token)
+                    .getBody();
+        } catch (Exception e) {
+            claims = null;
+        }
+        return claims;
+    }
+
+    private Date generateExpirationDate() {
+        return new Date(System.currentTimeMillis() + expiration * 1000);
+    }
+
+    private Boolean isTokenExpired(String token) {
+        final Date expiration = getExpirationDateFromToken(token);
+        return expiration.before(new Date());
+    }
+
+    private Boolean isCreatedBeforeLastPasswordReset(Date created, Date lastPasswordReset) {
+        return (lastPasswordReset != null && created.before(lastPasswordReset));
+    }
+
+    public String generateToken(UserDetails userDetails) {
+        Map<String, Object> claims = new HashMap<>();
+        claims.put(CLAIM_KEY_USERNAME, userDetails.getUsername());
+        claims.put(CLAIM_KEY_CREATED, new Date());
+        return generateToken(claims);
+    }
+
+    String generateToken(Map<String, Object> claims) {
+        return Jwts.builder()
+                .setClaims(claims)
+                .setExpiration(generateExpirationDate())
+                .signWith(SignatureAlgorithm.HS512, secret)
+                .compact();
+    }
+
+    public Boolean canTokenBeRefreshed(String token, Date lastPasswordReset) {
+        final Date created = getCreatedDateFromToken(token);
+        return !isCreatedBeforeLastPasswordReset(created, lastPasswordReset)
+                && !isTokenExpired(token);
+    }
+
+    public String refreshToken(String token) {
+        String refreshedToken;
+        try {
+            final Claims claims = getClaimsFromToken(token);
+            claims.put(CLAIM_KEY_CREATED, new Date());
+            refreshedToken = generateToken(claims);
+        } catch (Exception e) {
+            refreshedToken = null;
+        }
+        return refreshedToken;
+    }
+    // 只是判定用户名是否一致 不去判定是否失效
+    public Boolean validateToken(String token, UserDetails userDetails) {
+        User user = (User) userDetails;
+        final String username = getUsernameFromToken(token);
+//        final Date created = getCreatedDateFromToken(token);
+        //final Date expiration = getExpirationDateFromToken(token);
+        return username.equals(user.getUsername());
+//        return (
+//                username.equals(user.getUsername())
+//                        && !isTokenExpired(token)
+//                        && !isCreatedBeforeLastPasswordReset(created, null));
+    }
+}

+ 0 - 53
VisualInspection_server/src/main/java/com/xintong/visualinspection/securityTools/MyAccessDecisionManager.java

@@ -1,53 +0,0 @@
-package com.xintong.visualinspection.securityTools;
-
-import org.springframework.security.access.AccessDecisionManager;
-import org.springframework.security.access.AccessDeniedException;
-import org.springframework.security.access.ConfigAttribute;
-import org.springframework.security.authentication.InsufficientAuthenticationException;
-import org.springframework.security.core.Authentication;
-import org.springframework.security.core.GrantedAuthority;
-import org.springframework.stereotype.Service;
-
-import java.util.Collection;
-import java.util.Iterator;
-/**
- * 文件名:MyAccessDecisionManager
- * 版本信息:日期:2017/3/31 Copyright 江苏省交通规划设计院 Corporation 2017 版权所有.
- */
-@Service
-public class MyAccessDecisionManager implements AccessDecisionManager {
-    @Override
-    public void decide(Authentication authentication, Object object, Collection<ConfigAttribute> configAttributes) throws AccessDeniedException, InsufficientAuthenticationException {
-
-        if(null== configAttributes || configAttributes.size() <=0) {
-            return;
-        }
-        ConfigAttribute c;
-        String needRole;
-        for(Iterator<ConfigAttribute> iter = configAttributes.iterator(); iter.hasNext(); ) {
-            c = iter.next();
-            needRole = c.getAttribute();
-            for(GrantedAuthority ga : authentication.getAuthorities()) {
-                if(needRole.trim().equals(ga.getAuthority())) {
-                    return;
-                }
-            }
-        }
-        throw new AccessDeniedException("no right");
-
-
-
-    }
-
-
-
-    @Override
-    public boolean supports(ConfigAttribute attribute) {
-        return true;
-    }
-
-    @Override
-    public boolean supports(Class<?> clazz) {
-        return true;
-    }
-}

+ 0 - 77
VisualInspection_server/src/main/java/com/xintong/visualinspection/securityTools/MyFilterSecurityInterceptor.java

@@ -1,77 +0,0 @@
-package com.xintong.visualinspection.securityTools;
-import javax.servlet.Filter;
-import javax.servlet.FilterChain;
-import javax.servlet.FilterConfig;
-import javax.servlet.ServletException;
-import javax.servlet.ServletRequest;
-import javax.servlet.ServletResponse;
-
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.security.access.SecurityMetadataSource;
-import org.springframework.security.access.intercept.AbstractSecurityInterceptor;
-import org.springframework.security.access.intercept.InterceptorStatusToken;
-import org.springframework.security.web.FilterInvocation;
-import org.springframework.security.web.access.intercept.FilterInvocationSecurityMetadataSource;
-import org.springframework.stereotype.Service;
-
-import java.io.IOException;
-/**
- * 文件名:MyFilterSecurityInterceptor
- * 版本信息:日期:2017/3/31 Copyright 江苏省交通规划设计院 Corporation 2017 版权所有.
- */
-@Service
-public class MyFilterSecurityInterceptor extends AbstractSecurityInterceptor implements Filter {
-
-
-    @Autowired
-    private FilterInvocationSecurityMetadataSource securityMetadataSource;
-
-    @Autowired
-    public void setMyAccessDecisionManager(MyAccessDecisionManager myAccessDecisionManager) {
-        super.setAccessDecisionManager(myAccessDecisionManager);
-    }
-
-
-    @Override
-    public void init(FilterConfig filterConfig) throws ServletException {
-
-    }
-
-    @Override
-    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
-
-        FilterInvocation fi = new FilterInvocation(request, response, chain);
-        invoke(fi);
-    }
-
-
-    public void invoke(FilterInvocation fi) throws IOException, ServletException {
-//fi里面有一个被拦截的url
-//里面调用MyInvocationSecurityMetadataSource的getAttributes(Object object)这个方法获取fi对应的所有权限
-//再调用MyAccessDecisionManager的decide方法来校验用户的权限是否足够
-        InterceptorStatusToken token = super.beforeInvocation(fi);
-        try {
-//执行下一个拦截器
-            fi.getChain().doFilter(fi.getRequest(), fi.getResponse());
-        } finally {
-            super.afterInvocation(token, null);
-        }
-    }
-
-
-    @Override
-    public void destroy() {
-
-    }
-
-    @Override
-    public Class<?> getSecureObjectClass() {
-        return FilterInvocation.class;
-
-    }
-
-    @Override
-    public SecurityMetadataSource obtainSecurityMetadataSource() {
-        return this.securityMetadataSource;
-    }
-}

+ 0 - 40
VisualInspection_server/src/main/java/com/xintong/visualinspection/securityTools/MyGrantedAuthority.java

@@ -1,40 +0,0 @@
-package com.xintong.visualinspection.securityTools;
-
-import lombok.Data;
-import org.springframework.security.core.GrantedAuthority;
-
-/**
- * Created by yangyibo on 17/2/15.
- */
-@Data
-public class MyGrantedAuthority implements GrantedAuthority {
-
-    private String url;
-    private String method;
-
-    public String getPermissionUrl() {
-        return url;
-    }
-
-    public void setPermissionUrl(String permissionUrl) {
-        this.url = permissionUrl;
-    }
-
-    public String getMethod() {
-        return method;
-    }
-
-    public void setMethod(String method) {
-        this.method = method;
-    }
-
-    public MyGrantedAuthority(String url, String method) {
-        this.url = url;
-        this.method = method;
-    }
-
-    @Override
-    public String getAuthority() {
-        return this.url + ";" + this.method;
-    }
-}

+ 0 - 76
VisualInspection_server/src/main/java/com/xintong/visualinspection/securityTools/MyInvocationSecurityMetadataSourceService.java

@@ -1,76 +0,0 @@
-package com.xintong.visualinspection.securityTools;
-
-import com.xintong.visualinspection.bean.Permission;
-import com.xintong.visualinspection.dao.master.PermissionDao;
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.security.access.ConfigAttribute;
-import org.springframework.security.access.SecurityConfig;
-import org.springframework.security.web.FilterInvocation;
-import org.springframework.security.web.access.intercept.FilterInvocationSecurityMetadataSource;
-import org.springframework.security.web.util.matcher.AntPathRequestMatcher;
-import org.springframework.stereotype.Service;
-
-import javax.servlet.http.HttpServletRequest;
-import java.util.*;
-/**
- * 文件名:MyInvocationSecurityMetadataSourceService
- * 版本信息:日期:2017/3/31 Copyright 江苏省交通规划设计院 Corporation 2017 版权所有.
- */
-
-
-
-/**
- * Created by yangyibo on 17/1/19.
- */
-@Service
-public class MyInvocationSecurityMetadataSourceService  implements
-        FilterInvocationSecurityMetadataSource {
-
-    @Autowired
-    private PermissionDao permissionDao;
-
-    private HashMap<String, Collection<ConfigAttribute>> map =null;
-
-    /**
-     * 加载资源,初始化资源变量
-     */
-    public void loadResourceDefine(){
-        map = new HashMap<>();
-        Collection<ConfigAttribute> array;
-        ConfigAttribute cfg;
-        List<Permission> permissions = permissionDao.findAll();
-        for(Permission permission : permissions) {
-            array = new ArrayList<>();
-            cfg = new SecurityConfig(permission.getName());
-            array.add(cfg);
-            map.put(permission.getUrl(), array);
-        }
-
-    }
-
-    @Override
-    public Collection<ConfigAttribute> getAttributes(Object object) throws IllegalArgumentException {
-        if(map ==null) loadResourceDefine();
-        HttpServletRequest request = ((FilterInvocation) object).getHttpRequest();
-        AntPathRequestMatcher matcher;
-        String resUrl;
-        for(Iterator<String> iter = map.keySet().iterator(); iter.hasNext(); ) {
-            resUrl = iter.next();
-            matcher = new AntPathRequestMatcher(resUrl);
-            if(matcher.matches(request)) {
-                return map.get(resUrl);
-            }
-        }
-        return null;
-    }
-
-    @Override
-    public Collection<ConfigAttribute> getAllConfigAttributes() {
-        return null;
-    }
-
-    @Override
-    public boolean supports(Class<?> clazz) {
-        return true;
-    }
-}

+ 27 - 0
VisualInspection_server/src/main/java/com/xintong/visualinspection/securityTools/RedisCacheUtil.java

@@ -0,0 +1,27 @@
+package com.xintong.visualinspection.securityTools;
+
+import java.util.concurrent.TimeUnit;
+
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.data.redis.core.RedisTemplate;
+import org.springframework.security.core.userdetails.UserDetails;
+import org.springframework.stereotype.Component;
+
+import com.xintong.visualinspection.bean.User;
+
+@Component
+public class RedisCacheUtil {
+	@Autowired
+	private RedisTemplate redisTemplate;
+	
+	
+	public UserDetails getUserByUserName(String username){
+		return (UserDetails)redisTemplate.opsForValue().get(username);
+	}
+	
+	public void setUser(String token,UserDetails user,int timeout){
+		redisTemplate.opsForValue().set(token, user, timeout, TimeUnit.MILLISECONDS);
+	}
+	
+
+}

+ 2 - 0
VisualInspection_server/src/main/java/com/xintong/visualinspection/securityTools/RedisConf.java

@@ -6,6 +6,8 @@ import com.alibaba.fastjson.serializer.JSONSerializableSerializer;
 import com.fasterxml.jackson.annotation.JsonAutoDetect;
 import com.fasterxml.jackson.annotation.PropertyAccessor;
 import com.fasterxml.jackson.databind.ObjectMapper;
+
+import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
 import org.springframework.cache.CacheManager;
 import org.springframework.cache.annotation.CachingConfigurerSupport;
 import org.springframework.cache.annotation.EnableCaching;

+ 41 - 18
VisualInspection_server/src/main/java/com/xintong/visualinspection/securityTools/WebSecurityConfig.java

@@ -3,6 +3,7 @@ package com.xintong.visualinspection.securityTools;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.context.annotation.Bean;
 import org.springframework.context.annotation.Configuration;
+import org.springframework.http.HttpMethod;
 import org.springframework.security.authentication.encoding.Md5PasswordEncoder;
 import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
 import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity;
@@ -10,7 +11,8 @@ import org.springframework.security.config.annotation.web.builders.HttpSecurity;
 import org.springframework.security.config.annotation.web.builders.WebSecurity;
 import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
 import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
-import org.springframework.security.web.access.intercept.FilterSecurityInterceptor;
+import org.springframework.security.config.http.SessionCreationPolicy;
+import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;
 
 import com.xintong.visualinspection.service.UserService;
 
@@ -24,11 +26,13 @@ import com.xintong.visualinspection.service.UserService;
 public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
 
     @Autowired
-    private MyFilterSecurityInterceptor myFilterSecurityInterceptor;
-
-    @Autowired
     private UserService userService;
 
+    @Bean
+    public JwtAuthenticationTokenFilter authenticationTokenFilterBean() throws Exception {
+        return new JwtAuthenticationTokenFilter();
+    }
+    
     @Override
     protected void configure(AuthenticationManagerBuilder auth) throws Exception {
         auth.userDetailsService(userService).passwordEncoder(passwordEncoder());//user Details Service验证
@@ -42,20 +46,37 @@ public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
 
     @Override
     protected void configure(HttpSecurity http) throws Exception {
-        http.authorizeRequests()
-                .anyRequest()
-                .authenticated() //任何请求,登录后可以访问
-                .and()
-                .formLogin()
-                .loginPage("/login")
-                .failureUrl("/login?error")
-                .permitAll() //登录页面用户任意访问
-                .and()
-                .logout().permitAll(); //注销行为任意访问
-
-
-        http.addFilterBefore(myFilterSecurityInterceptor, FilterSecurityInterceptor.class).csrf().disable();
-
+    	
+    	http
+         // 由于使用的是JWT,我们这里不需要csrf
+         .csrf().disable()
+         // 基于token,所以不需要session
+         .sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS).and()
+         .authorizeRequests()
+         //.antMatchers(HttpMethod.OPTIONS, "/**").permitAll()
+         // 允许对于网站静态资源的无授权访问
+         .antMatchers(
+                 HttpMethod.GET,
+                 "/",
+                 "/*.html",
+                 "/favicon.ico",
+                 "/**/*.html",
+                 "/**/*.css",
+                 "/**/*.js"
+         ).permitAll()
+         // 对于获取token的rest api要允许匿名访问
+         .antMatchers("/user/auth/**").permitAll()
+         // 除上面外的所有请求全部需要鉴权认证
+         .anyRequest().authenticated();
+    	
+    	// 禁用缓存
+        http.headers().cacheControl();
+        
+        http
+        .addFilterBefore(authenticationTokenFilterBean(), UsernamePasswordAuthenticationFilter.class);
+    	
+    	
+  
     }
 
     /**
@@ -67,4 +88,6 @@ public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
         return new Md5PasswordEncoder();
 
     }
+    
+  
 }

+ 8 - 0
VisualInspection_server/src/main/java/com/xintong/visualinspection/service/AuthService.java

@@ -0,0 +1,8 @@
+package com.xintong.visualinspection.service;
+
+import com.xintong.visualinspection.bean.User;
+
+public interface AuthService {
+	 public  User login(String username, String password);
+	 public  String refresh(String oldToken);
+}

+ 81 - 0
VisualInspection_server/src/main/java/com/xintong/visualinspection/service/impl/AuthServiceImpl.java

@@ -0,0 +1,81 @@
+package com.xintong.visualinspection.service.impl;
+
+import java.util.concurrent.TimeUnit;
+
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.data.redis.core.RedisTemplate;
+import org.springframework.security.authentication.AuthenticationManager;
+import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
+import org.springframework.security.core.Authentication;
+import org.springframework.security.core.context.SecurityContextHolder;
+import org.springframework.security.core.userdetails.UserDetailsService;
+import org.springframework.stereotype.Service;
+
+import com.xintong.visualinspection.bean.User;
+import com.xintong.visualinspection.securityTools.JwtTokenUtil;
+import com.xintong.visualinspection.securityTools.RedisCacheUtil;
+import com.xintong.visualinspection.service.AuthService;
+import com.xintong.visualinspection.service.BaseService;
+
+@Service
+public class AuthServiceImpl extends BaseService implements AuthService {
+
+
+	    private AuthenticationManager authenticationManager;
+	    private UserDetailsService userDetailsService;
+	    private JwtTokenUtil jwtTokenUtil;
+	    
+	    
+		@Value("${jwt.expiration}")
+		private int expiration;
+		
+
+		@Autowired
+		private RedisCacheUtil redisCacheUtil;
+	    
+
+	    @Value("${jwt.tokenHead}")
+	    private String tokenHead;
+
+	    @Autowired
+	    public AuthServiceImpl(
+	            AuthenticationManager authenticationManager,
+	            UserDetailsService userDetailsService,
+	            JwtTokenUtil jwtTokenUtil) {
+	        this.authenticationManager = authenticationManager;
+	        this.userDetailsService = userDetailsService;
+	        this.jwtTokenUtil = jwtTokenUtil;
+	    }
+	  
+
+	    @Override
+	    public User login(String username, String password) {
+	        UsernamePasswordAuthenticationToken upToken = new UsernamePasswordAuthenticationToken(username, password);
+	        final Authentication authentication = authenticationManager.authenticate(upToken);
+	        SecurityContextHolder.getContext().setAuthentication(authentication);
+
+	        User userDetails =(User) userDetailsService.loadUserByUsername(username);
+	        
+	        final String token = jwtTokenUtil.generateToken(userDetails);
+	        userDetails.setToken(token);
+	        
+	        redisCacheUtil.setUser(userDetails.getUsername(), userDetails, expiration);
+	       
+	        
+	        return userDetails;
+	    }
+
+	    @Override
+	    public String refresh(String oldToken) {
+	        final String token = oldToken.substring(tokenHead.length());
+	        String username = jwtTokenUtil.getUsernameFromToken(token);
+	        User user = (User) userDetailsService.loadUserByUsername(username);
+	        if (jwtTokenUtil.canTokenBeRefreshed(token, null)){
+	            return jwtTokenUtil.refreshToken(token);
+	        }
+	        return null;
+	    }
+	
+
+}

+ 11 - 10
VisualInspection_server/src/main/java/com/xintong/visualinspection/service/impl/UserServiceImpl.java

@@ -5,6 +5,7 @@ import com.xintong.visualinspection.bean.User;
 import com.xintong.visualinspection.dao.cluster.UserInfoDao;
 import com.xintong.visualinspection.dao.master.PermissionDao;
 import com.xintong.visualinspection.dao.master.UserDao;
+import com.xintong.visualinspection.pojo.SimpleGrantedAuthority;
 import com.xintong.visualinspection.service.BaseService;
 import com.xintong.visualinspection.service.UserService;
 import lombok.Data;
@@ -14,7 +15,6 @@ import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.cache.annotation.Cacheable;
 import org.springframework.data.redis.core.RedisTemplate;
 import org.springframework.security.core.GrantedAuthority;
-import org.springframework.security.core.authority.SimpleGrantedAuthority;
 import org.springframework.security.core.userdetails.UserDetails;
 import org.springframework.security.core.userdetails.UsernameNotFoundException;
 import org.springframework.stereotype.Service;
@@ -54,14 +54,14 @@ public class UserServiceImpl extends BaseService implements UserService {
     @Override
 //    @Cacheable(value = "usercache",keyGenerator = "keyGenerator")
     public User getOne(Long id) {
-        User user = new User();
-        user.setUsername("aa"+count++);
-        redisTemplate.opsForValue().set(user.getUsername(), user);
-
-        
-        User u = (User) redisTemplate.opsForValue().get("aa"+(count-2));
-
-        System.out.println(u.toString()+"dsa");
+//        User user = new User();
+//        user.setUsername("aa"+count++);
+//        redisTemplate.opsForValue().set(user.getUsername(), user);
+//
+//        
+//        User u = (User) redisTemplate.opsForValue().get("aa"+(count-2));
+//
+//        System.out.println(u.toString()+"dsa");
 
         return getUserById(id);
     }
@@ -107,7 +107,8 @@ public class UserServiceImpl extends BaseService implements UserService {
                     grantedAuthorities.add(grantedAuthority);
                 }
             }
-            return new User(user.getUsername(), user.getPassword(), grantedAuthorities);
+            user.setGrantedAuthorities(grantedAuthorities);
+            return user;
         } else {
             throw new UsernameNotFoundException("admin: " + username + " do not exist!");
         }

+ 12 - 7
VisualInspection_server/src/main/resources/application.properties

@@ -70,13 +70,11 @@ spring.redis.timeout=0
 
 
 
-log4j.logger.org.thymeleaf=DEBUG
-log4j.logger.org.thymeleaf.TemplateEngine.CONFIG=DEBUG
-log4j.logger.org.thymeleaf.TemplateEngine.TIMER=DEBUG
-log4j.logger.org.thymeleaf.TemplateEngine.cache.TEMPLATE_CACHE=DEBUG
-log4j.logger.org.thymeleaf.TemplateEngine.cache.FRAGMENT_CACHE=DEBUG
-log4j.logger.org.thymeleaf.TemplateEngine.cache.MESSAGE_CACHE=DEBUG
-log4j.logger.org.thymeleaf.TemplateEngine.cache.EXPRESSION_CACHE=DEBUG
+logging.level.root=INFO
+logging.level.org.springframework.web=DEBUG
+logging.level.org.springframework.data=DEBUG
+logging.level.org.springframework.security=DEBUG
+logging.level.org.hibernate=ERROR
 
 
 
@@ -84,6 +82,13 @@ spring.devtools.restart.enabled=true
 
 
 
+# JWT
+jwt.header=Authorization
+jwt.secret=mySecret
+jwt.expiration=604800
+jwt.tokenHead=XinTong 
+
+
 management.shell.auth.simple.user.name=wen
 management.shell.auth.simple.user.password=wen
 management.shell.auth.type=simple