> converters) {
20 | converters.add(jackson2HttpMessageConverter());
21 | }
22 |
23 | @Bean
24 | public MappingJackson2HttpMessageConverter jackson2HttpMessageConverter() {
25 | //set HTTP Message converter using a JSON implementation.
26 | MappingJackson2HttpMessageConverter jsonMessageConverter = new MappingJackson2HttpMessageConverter();
27 | // Add supported media type returned by BI API.
28 | List supportedMediaTypes = new ArrayList();
29 | supportedMediaTypes.add(new MediaType("text", "plain"));
30 | supportedMediaTypes.add(new MediaType("application", "json"));
31 | jsonMessageConverter.setSupportedMediaTypes(supportedMediaTypes);
32 | return jsonMessageConverter;
33 | }
34 |
35 | }
36 |
--------------------------------------------------------------------------------
/car_admin/src/main/java/com/chinawiserv/admin/config/security/CustomerAccessDeniedHandler.java:
--------------------------------------------------------------------------------
1 | package com.chinawiserv.admin.config.security;
2 |
3 | import lombok.extern.slf4j.Slf4j;
4 | import org.springframework.security.access.AccessDeniedException;
5 | import org.springframework.security.core.Authentication;
6 | import org.springframework.security.core.context.SecurityContextHolder;
7 | import org.springframework.security.web.access.AccessDeniedHandler;
8 | import org.springframework.stereotype.Component;
9 |
10 | import javax.servlet.ServletException;
11 | import javax.servlet.http.HttpServletRequest;
12 | import javax.servlet.http.HttpServletResponse;
13 | import java.io.IOException;
14 |
15 | /**
16 | * handle 403 page
17 | *
18 | * Created by sungang on 2017/10/24.
19 | */
20 | @Component
21 | @Slf4j
22 | public class CustomerAccessDeniedHandler implements AccessDeniedHandler {
23 |
24 | @Override
25 | public void handle(HttpServletRequest httpServletRequest,
26 | HttpServletResponse httpServletResponse,
27 | AccessDeniedException e) throws IOException, ServletException {
28 |
29 | Authentication auth = SecurityContextHolder.getContext().getAuthentication();
30 | if (auth != null) {
31 | log.info("用户: '" + auth.getName()
32 | + " 无权限访问URL : "
33 | + httpServletRequest.getRequestURI());
34 | }
35 | httpServletResponse.setStatus(403);
36 | httpServletResponse.sendRedirect(httpServletRequest.getContextPath() + "/api/login/403?url=" + httpServletRequest.getMethod() + "路径>>" + httpServletRequest.getRequestURI());
37 |
38 | }
39 | }
40 |
--------------------------------------------------------------------------------
/car_admin/src/main/java/com/chinawiserv/admin/config/security/CustomerAuthenticationProvider.java:
--------------------------------------------------------------------------------
1 | package com.chinawiserv.admin.config.security;
2 |
3 | import com.chinawiserv.admin.config.security.service.JwtUserDetailsServiceImpl;
4 | import lombok.extern.slf4j.Slf4j;
5 | import org.springframework.beans.factory.annotation.Autowired;
6 | import org.springframework.security.authentication.AuthenticationProvider;
7 | import org.springframework.security.authentication.BadCredentialsException;
8 | import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
9 | import org.springframework.security.core.Authentication;
10 | import org.springframework.security.core.AuthenticationException;
11 | import org.springframework.security.core.userdetails.UserDetails;
12 | import org.springframework.stereotype.Component;
13 |
14 | /**
15 | * Created by sungang on 2017/10/24.
16 | */
17 | @Component
18 | @Slf4j
19 | public class CustomerAuthenticationProvider implements AuthenticationProvider {
20 | @Autowired
21 | private JwtUserDetailsServiceImpl userDetailsService;
22 | @Override
23 | public Authentication authenticate(Authentication authentication) throws AuthenticationException {
24 | log.info("用户输入的用户名是:{}", authentication.getName());
25 | log.info("用户输入的密码是:{}", authentication.getCredentials());
26 | // 根据用户输入的用户名获取该用户名已经在服务器上存在的用户详情,如果没有则返回null
27 | UserDetails userDetails = this.userDetailsService.loadUserByUsername(authentication.getName());
28 | try {
29 | log.info("服务器上已经保存的用户名是:" + userDetails.getUsername());
30 | log.info("服务器上保存的该用户名对应的密码是: " + userDetails.getPassword());
31 | log.info("服务器上保存的该用户对应的权限是:" + userDetails.getAuthorities());
32 | //判断用户输入的密码和服务器上已经保存的密码是否一致
33 | if (authentication.getCredentials().equals(userDetails.getPassword())) {
34 | log.info("认证成功!");
35 | //如果验证通过,将返回一个UsernamePasswordAuthenticaionToken对象
36 | return new UsernamePasswordAuthenticationToken(userDetails, authentication.getCredentials(), userDetails.getAuthorities());
37 | }else{
38 | log.warn("认证失败, 密码输入不正确!");
39 | new BadCredentialsException("认证失败, 密码输入不正确!");
40 | }
41 | } catch (Exception e) {
42 | log.error("认证失败, error message is: " , e);
43 | throw e;
44 | }
45 | //如果验证不通过将抛出异常或者返回null
46 | return null;
47 | }
48 |
49 |
50 |
51 | //告诉身份验证的功能只能使用UsernamePasswordAuthenticationToken对象。
52 | @Override
53 | public boolean supports(Class> authentication) {
54 | return true;
55 | }
56 | }
57 |
--------------------------------------------------------------------------------
/car_admin/src/main/java/com/chinawiserv/admin/config/security/JwtAuthenticationEntryPoint.java:
--------------------------------------------------------------------------------
1 | package com.chinawiserv.admin.config.security;
2 |
3 | import org.springframework.security.core.AuthenticationException;
4 | import org.springframework.security.web.AuthenticationEntryPoint;
5 | import org.springframework.stereotype.Component;
6 |
7 | import javax.servlet.http.HttpServletRequest;
8 | import javax.servlet.http.HttpServletResponse;
9 | import java.io.IOException;
10 | import java.io.Serializable;
11 |
12 | @Component
13 | public class JwtAuthenticationEntryPoint implements AuthenticationEntryPoint, Serializable {
14 |
15 | private static final long serialVersionUID = -8970718410437077606L;
16 |
17 | @Override
18 | public void commence(HttpServletRequest request,
19 | HttpServletResponse response,
20 | AuthenticationException authException) throws IOException {
21 | response.sendError(HttpServletResponse.SC_UNAUTHORIZED, "Unauthorized");
22 | }
23 | }
--------------------------------------------------------------------------------
/car_admin/src/main/java/com/chinawiserv/admin/config/security/JwtAuthenticationRequest.java:
--------------------------------------------------------------------------------
1 | package com.chinawiserv.admin.config.security;
2 |
3 | import java.io.Serializable;
4 |
5 | /**
6 | * Created by stephan on 20.03.16.
7 | */
8 | public class JwtAuthenticationRequest implements Serializable {
9 |
10 | private static final long serialVersionUID = -8445943548965154778L;
11 |
12 | private String username;
13 | private String password;
14 |
15 | public JwtAuthenticationRequest() {
16 | super();
17 | }
18 |
19 | public JwtAuthenticationRequest(String username, String password) {
20 | this.setUsername(username);
21 | this.setPassword(password);
22 | }
23 |
24 | public String getUsername() {
25 | return this.username;
26 | }
27 |
28 | public void setUsername(String username) {
29 | this.username = username;
30 | }
31 |
32 | public String getPassword() {
33 | return this.password;
34 | }
35 |
36 | public void setPassword(String password) {
37 | this.password = password;
38 | }
39 | }
40 |
--------------------------------------------------------------------------------
/car_admin/src/main/java/com/chinawiserv/admin/config/security/JwtAuthenticationTokenFilter.java:
--------------------------------------------------------------------------------
1 | package com.chinawiserv.admin.config.security;
2 |
3 | import java.io.IOException;
4 | import javax.servlet.FilterChain;
5 | import javax.servlet.ServletException;
6 | import javax.servlet.http.HttpServletRequest;
7 | import javax.servlet.http.HttpServletResponse;
8 |
9 | import lombok.extern.slf4j.Slf4j;
10 | import org.apache.commons.logging.Log;
11 | import org.apache.commons.logging.LogFactory;
12 | import org.springframework.beans.factory.annotation.Autowired;
13 | import org.springframework.beans.factory.annotation.Value;
14 | import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
15 | import org.springframework.security.core.context.SecurityContextHolder;
16 | import org.springframework.security.core.userdetails.UserDetails;
17 | import org.springframework.security.core.userdetails.UserDetailsService;
18 | import org.springframework.security.web.authentication.WebAuthenticationDetailsSource;
19 | import org.springframework.web.filter.OncePerRequestFilter;
20 |
21 | /**
22 | * 首先会去到 OncePerRequestFilter 类的 doFilter 方法,执行doFilterInternal 方法
23 | */
24 | @Slf4j
25 | public class JwtAuthenticationTokenFilter extends OncePerRequestFilter {
26 |
27 | @Autowired
28 | private UserDetailsService userDetailsService;
29 |
30 | @Autowired
31 | private JwtTokenUtil jwtTokenUtil;
32 |
33 | @Value("${jwt.header}")
34 | private String tokenHeader;
35 |
36 | @Override
37 | protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain chain) throws ServletException, IOException {
38 | String authToken = request.getHeader(this.tokenHeader);
39 | String username;
40 | try {
41 | username = jwtTokenUtil.getUsernameFromToken(authToken);
42 | } catch (IllegalArgumentException e) {
43 | username = null;
44 | }
45 | log.info("验证 authentication für user:{} " , username);
46 | if (username != null && SecurityContextHolder.getContext().getAuthentication() == null) {
47 | UserDetails userDetails = this.userDetailsService.loadUserByUsername(username);
48 | if (jwtTokenUtil.validateToken(authToken, userDetails)) {
49 | UsernamePasswordAuthenticationToken authentication = new UsernamePasswordAuthenticationToken(userDetails, null, userDetails.getAuthorities());
50 | authentication.setDetails(new WebAuthenticationDetailsSource().buildDetails(request));
51 | log.info("认证用户: " + username + ", 设置 Security Context");
52 | SecurityContextHolder.getContext().setAuthentication(authentication);
53 | }
54 | }
55 | chain.doFilter(request, response);
56 | }
57 | }
--------------------------------------------------------------------------------
/car_admin/src/main/java/com/chinawiserv/admin/config/security/JwtTokenUtil.java:
--------------------------------------------------------------------------------
1 | package com.chinawiserv.admin.config.security;
2 |
3 | import com.chinawiserv.admin.config.security.utils.TimeProvider;
4 | import io.jsonwebtoken.Claims;
5 | import io.jsonwebtoken.Jwts;
6 | import io.jsonwebtoken.SignatureAlgorithm;
7 | import org.springframework.beans.factory.annotation.Autowired;
8 | import org.springframework.beans.factory.annotation.Value;
9 | import org.springframework.mobile.device.Device;
10 | import org.springframework.security.core.userdetails.UserDetails;
11 | import org.springframework.stereotype.Component;
12 |
13 | import java.io.Serializable;
14 | import java.util.Date;
15 | import java.util.HashMap;
16 | import java.util.Map;
17 | import java.util.function.Function;
18 |
19 | @Component
20 | public class JwtTokenUtil implements Serializable {
21 |
22 | private static final long serialVersionUID = -3301605591108950415L;
23 |
24 | static final String CLAIM_KEY_USERNAME = "sub";
25 | static final String CLAIM_KEY_AUDIENCE = "aud";
26 | static final String CLAIM_KEY_CREATED = "iat";
27 |
28 | static final String AUDIENCE_UNKNOWN = "unknown";
29 | static final String AUDIENCE_WEB = "web";
30 | static final String AUDIENCE_MOBILE = "mobile";
31 | static final String AUDIENCE_TABLET = "tablet";
32 |
33 | @Autowired
34 | private TimeProvider timeProvider;
35 |
36 | @Value("${jwt.secret}")
37 | private String secret;
38 |
39 | @Value("${jwt.expiration}")
40 | private Long expiration;
41 |
42 | public String getUsernameFromToken(String token) {
43 | return getClaimFromToken(token, Claims::getSubject);
44 | }
45 |
46 | public Date getIssuedAtDateFromToken(String token) {
47 | return getClaimFromToken(token, Claims::getIssuedAt);
48 | }
49 |
50 | public Date getExpirationDateFromToken(String token) {
51 | return getClaimFromToken(token, Claims::getExpiration);
52 | }
53 |
54 | public String getAudienceFromToken(String token) {
55 | return getClaimFromToken(token, Claims::getAudience);
56 | }
57 |
58 | public T getClaimFromToken(String token, Function claimsResolver) {
59 | final Claims claims = getAllClaimsFromToken(token);
60 | return claimsResolver.apply(claims);
61 | }
62 |
63 | private Claims getAllClaimsFromToken(String token) {
64 | return Jwts.parser()
65 | .setSigningKey(secret)
66 | .parseClaimsJws(token)
67 | .getBody();
68 | }
69 |
70 | private Boolean isTokenExpired(String token) {
71 | final Date expiration = getExpirationDateFromToken(token);
72 | return expiration.before(timeProvider.now());
73 | }
74 |
75 | private Boolean isCreatedBeforeLastPasswordReset(Date created, Date lastPasswordReset) {
76 | return (lastPasswordReset != null && created.before(lastPasswordReset));
77 | }
78 |
79 | private String generateAudience(Device device) {
80 | String audience = AUDIENCE_UNKNOWN;
81 | if (device.isNormal()) {
82 | audience = AUDIENCE_WEB;
83 | } else if (device.isTablet()) {
84 | audience = AUDIENCE_TABLET;
85 | } else if (device.isMobile()) {
86 | audience = AUDIENCE_MOBILE;
87 | }
88 | return audience;
89 | }
90 |
91 | private Boolean ignoreTokenExpiration(String token) {
92 | String audience = getAudienceFromToken(token);
93 | return (AUDIENCE_TABLET.equals(audience) || AUDIENCE_MOBILE.equals(audience));
94 | }
95 |
96 | public String generateToken(UserDetails userDetails, Device device) {
97 | Map claims = new HashMap<>();
98 | return doGenerateToken(claims, userDetails.getUsername(), generateAudience(device));
99 | }
100 |
101 | private String doGenerateToken(Map claims, String subject, String audience) {
102 | final Date createdDate = timeProvider.now();
103 | final Date expirationDate = new Date(createdDate.getTime() + expiration * 1000);
104 |
105 | System.out.println("doGenerateToken " + createdDate);
106 |
107 | return Jwts.builder()
108 | .setClaims(claims)
109 | .setSubject(subject)
110 | .setAudience(audience)
111 | .setIssuedAt(createdDate)
112 | .setExpiration(expirationDate)
113 | .signWith(SignatureAlgorithm.HS512, secret)
114 | .compact();
115 | }
116 |
117 | public Boolean canTokenBeRefreshed(String token, Date lastPasswordReset) {
118 | final Date created = getIssuedAtDateFromToken(token);
119 | return !isCreatedBeforeLastPasswordReset(created, lastPasswordReset)
120 | && (!isTokenExpired(token) || ignoreTokenExpiration(token));
121 | }
122 |
123 | public String refreshToken(String token) {
124 | final Claims claims = getAllClaimsFromToken(token);
125 | claims.setIssuedAt(timeProvider.now());
126 | return doRefreshToken(claims);
127 | }
128 |
129 | public String doRefreshToken(Claims claims) {
130 | return Jwts.builder()
131 | .setClaims(claims)
132 | .signWith(SignatureAlgorithm.HS512, secret)
133 | .compact();
134 | }
135 |
136 | public Boolean validateToken(String token, UserDetails userDetails) {
137 | JwtUser user = (JwtUser) userDetails;
138 | final String username = getUsernameFromToken(token);
139 | final Date created = getIssuedAtDateFromToken(token);
140 | //final Date expiration = getExpirationDateFromToken(token);
141 | return (
142 | username.equals(user.getUsername())
143 | && !isTokenExpired(token)
144 | && !isCreatedBeforeLastPasswordReset(created, user.getLastPasswordResetDate()));
145 | }
146 | }
--------------------------------------------------------------------------------
/car_admin/src/main/java/com/chinawiserv/admin/config/security/JwtUser.java:
--------------------------------------------------------------------------------
1 | package com.chinawiserv.admin.config.security;
2 |
3 | import java.util.Collection;
4 | import java.util.Date;
5 |
6 | import org.springframework.security.core.GrantedAuthority;
7 | import org.springframework.security.core.userdetails.UserDetails;
8 |
9 | import com.fasterxml.jackson.annotation.JsonIgnore;
10 |
11 | /**
12 | * Created by stephan on 20.03.16.
13 | */
14 | public class JwtUser implements UserDetails {
15 |
16 |
17 | private final Long id;
18 | private final String username;
19 | private final String password;
20 | private final String email;
21 | private final Collection extends GrantedAuthority> authorities;
22 | private final boolean enabled;
23 | private final Date lastPasswordResetDate;
24 |
25 | public JwtUser(Long id, String username, String password, String email, boolean enabled, Collection extends GrantedAuthority> authorities, Date lastPasswordResetDate) {
26 | this.id = id;
27 | this.username = username;
28 | this.email = email;
29 | this.password = password;
30 | this.enabled = enabled;
31 | this.authorities = authorities;
32 | this.lastPasswordResetDate = lastPasswordResetDate;
33 | }
34 |
35 | @JsonIgnore
36 | public Long getId() {
37 | return id;
38 | }
39 |
40 | @Override
41 | public String getUsername() {
42 | return username;
43 | }
44 |
45 | @JsonIgnore
46 | @Override
47 | public boolean isAccountNonExpired() {
48 | return true;
49 | }
50 |
51 | @JsonIgnore
52 | @Override
53 | public boolean isAccountNonLocked() {
54 | return true;
55 | }
56 |
57 | @JsonIgnore
58 | @Override
59 | public boolean isCredentialsNonExpired() {
60 | return true;
61 | }
62 |
63 | public String getEmail() {
64 | return email;
65 | }
66 |
67 | @JsonIgnore
68 | @Override
69 | public String getPassword() {
70 | return password;
71 | }
72 |
73 | @Override
74 | public boolean isEnabled() {
75 | return enabled;
76 | }
77 |
78 | @Override
79 | public Collection extends GrantedAuthority> getAuthorities() {
80 | return authorities;
81 | }
82 |
83 | @JsonIgnore
84 | public Date getLastPasswordResetDate() {
85 | return lastPasswordResetDate;
86 | }
87 | }
88 |
--------------------------------------------------------------------------------
/car_admin/src/main/java/com/chinawiserv/admin/config/security/JwtUserFactory.java:
--------------------------------------------------------------------------------
1 | package com.chinawiserv.admin.config.security;
2 |
3 | import java.util.List;
4 | import java.util.stream.Collectors;
5 |
6 | import com.chinawiserv.admin.config.security.url.UrlGrantedAuthority;
7 | import com.chinawiserv.admin.model.Permission;
8 | import com.chinawiserv.admin.model.User;
9 | import org.springframework.security.core.GrantedAuthority;
10 | import org.springframework.security.core.authority.SimpleGrantedAuthority;
11 |
12 | public final class JwtUserFactory {
13 |
14 | private JwtUserFactory() {
15 | }
16 |
17 | public static JwtUser create(User user) {
18 | return new JwtUser(
19 | user.getId(),
20 | user.getUsername(),
21 | user.getPassword(),
22 | user.getEmail(),
23 | user.getStatus() == 0 ? false : true,
24 | mapToGrantedAuthorities(user.getAuthorities()),
25 | user.getLastPasswordResetDate()
26 | );
27 | }
28 |
29 | private static List mapToGrantedAuthorities(List authorities) {
30 | return authorities.stream().map(authority -> new UrlGrantedAuthority(authority.getName(),authority.getPermissionUrl(), authority.getMethod())).collect(Collectors.toList());
31 | }
32 | }
33 |
--------------------------------------------------------------------------------
/car_admin/src/main/java/com/chinawiserv/admin/config/security/WebSecurityConfig.java:
--------------------------------------------------------------------------------
1 | package com.chinawiserv.admin.config.security;
2 |
3 | import com.chinawiserv.utils.encryption.EncryptionHelper;
4 | import org.springframework.beans.factory.annotation.Autowired;
5 | import org.springframework.context.annotation.Bean;
6 | import org.springframework.context.annotation.Configuration;
7 | import org.springframework.http.HttpMethod;
8 | import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
9 | import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity;
10 | import org.springframework.security.config.annotation.web.builders.HttpSecurity;
11 | import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
12 | import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
13 | import org.springframework.security.config.http.SessionCreationPolicy;
14 | import org.springframework.security.core.userdetails.UserDetailsService;
15 | import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
16 | import org.springframework.security.crypto.password.PasswordEncoder;
17 | import org.springframework.security.web.access.AccessDeniedHandler;
18 | import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;
19 |
20 | /**
21 | * Created by sungang on 2017/8/19.
22 | */
23 | @SuppressWarnings("SpringJavaAutowiringInspection")
24 | @Configuration
25 | @EnableWebSecurity
26 | @EnableGlobalMethodSecurity(prePostEnabled = true)
27 | public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
28 |
29 | /**
30 | * 自定义
31 | */
32 | @Autowired
33 | private CustomerAuthenticationProvider authProvider;
34 |
35 | @Autowired
36 | private JwtAuthenticationEntryPoint unauthorizedHandler;
37 |
38 | @Autowired
39 | private CustomerAccessDeniedHandler customerAccessDeniedHandler;
40 |
41 | // Spring会自动寻找同样类型的具体类注入,这里就是JwtUserDetailsServiceImpl了
42 | @Autowired
43 | private UserDetailsService userDetailsService;
44 |
45 |
46 | // @Autowired
47 | // public void configureAuthentication(AuthenticationManagerBuilder auth) throws Exception {
48 | // auth.authenticationProvider(authProvider)
49 | // // 设置UserDetailsService
50 | // .userDetailsService(this.userDetailsService)
51 | // // 使用BCrypt进行密码的hash
52 | // .passwordEncoder(passwordEncoder());
53 | //
54 | // }
55 |
56 | @Autowired
57 | public void configureAuthentication(AuthenticationManagerBuilder auth) throws Exception {
58 | auth/*.authenticationProvider(authenticationProvider)*/
59 | // 设置UserDetailsService
60 | .userDetailsService(this.userDetailsService)
61 | // 使用BCrypt进行密码的hash
62 | .passwordEncoder(passwordEncoder());
63 |
64 | }
65 | // 装载BCrypt密码编码器
66 | // @Bean
67 | // public PasswordEncoder passwordEncoder() {
68 | // return new BCryptPasswordEncoder();
69 | // }
70 |
71 | // 装载 密码编码器
72 | @Bean
73 | public PasswordEncoder passwordEncoder() {
74 | return new PasswordEncoder() {
75 | @Override
76 | public String encode(CharSequence rawPassword) {
77 | return EncryptionHelper.encrypt((String) rawPassword);
78 | }
79 |
80 | @Override
81 | public boolean matches(CharSequence rawPassword, String encodedPassword) {
82 | return encodedPassword.equals(EncryptionHelper.encrypt((String) rawPassword));
83 | }
84 | };
85 | }
86 |
87 | // @Bean
88 | // public JwtAuthenticationTokenFilter authenticationTokenFilterBean() throws Exception {
89 | // return new JwtAuthenticationTokenFilter();
90 | // }
91 |
92 | @Override
93 | protected void configure(HttpSecurity httpSecurity) throws Exception {
94 | httpSecurity
95 | //由于使用的是JWT,我们这里不需要csrf
96 | .csrf().disable()
97 | .exceptionHandling().authenticationEntryPoint(unauthorizedHandler).and()
98 | //
99 | .exceptionHandling().accessDeniedHandler(customerAccessDeniedHandler).and()
100 | // 基于token,所以不需要session
101 | .sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS).and()
102 | .authorizeRequests()
103 | //.antMatchers(HttpMethod.OPTIONS, "/**").permitAll()
104 | // 允许对于网站静态资源的无授权访问
105 | .antMatchers(
106 | HttpMethod.GET,
107 | "/",
108 | "/*.html",
109 | "/favicon.ico",
110 | "/**/*.html",
111 | "/**/*.css",
112 | "/**/*.js"
113 | ).permitAll()
114 | // 对于获取token的rest api要允许匿名访问
115 | .antMatchers("/api/login/**").permitAll()
116 | // 除上面外的所有请求全部需要鉴权认证
117 | .anyRequest().authenticated();
118 |
119 | // Custom JWT based security filter
120 | httpSecurity.addFilterBefore(authenticationTokenFilterBean(), UsernamePasswordAuthenticationFilter.class);
121 |
122 | // 禁用缓存
123 | httpSecurity.headers().cacheControl();
124 | }
125 |
126 |
127 | @Bean
128 | public JwtAuthenticationTokenFilter authenticationTokenFilterBean() throws Exception {
129 | return new JwtAuthenticationTokenFilter();
130 | }
131 | }
132 |
--------------------------------------------------------------------------------
/car_admin/src/main/java/com/chinawiserv/admin/config/security/service/JwtAuthenticationResponse.java:
--------------------------------------------------------------------------------
1 | package com.chinawiserv.admin.config.security.service;
2 |
3 | import java.io.Serializable;
4 |
5 | /**
6 | * Created by stephan on 20.03.16.
7 | */
8 | public class JwtAuthenticationResponse implements Serializable {
9 |
10 | private static final long serialVersionUID = 1250166508152483573L;
11 |
12 | private final String token;
13 |
14 | public JwtAuthenticationResponse(String token) {
15 | this.token = token;
16 | }
17 |
18 | public String getToken() {
19 | return this.token;
20 | }
21 | }
22 |
--------------------------------------------------------------------------------
/car_admin/src/main/java/com/chinawiserv/admin/config/security/service/JwtUserDetailsServiceImpl.java:
--------------------------------------------------------------------------------
1 | package com.chinawiserv.admin.config.security.service;
2 |
3 | import com.chinawiserv.admin.config.security.JwtUser;
4 | import com.chinawiserv.admin.config.security.JwtUserFactory;
5 | import com.chinawiserv.admin.mapper.UserMapper;
6 | import com.chinawiserv.admin.model.User;
7 | import com.chinawiserv.core.service.BaseService;
8 | import com.google.common.collect.Maps;
9 | import org.springframework.beans.factory.annotation.Autowired;
10 | import org.springframework.data.redis.core.RedisTemplate;
11 | import org.springframework.security.core.userdetails.UserDetails;
12 | import org.springframework.security.core.userdetails.UserDetailsService;
13 | import org.springframework.security.core.userdetails.UsernameNotFoundException;
14 | import org.springframework.stereotype.Service;
15 |
16 | import java.util.Map;
17 |
18 | /**
19 | * Created by stephan on 20.03.16.
20 | */
21 | @Service
22 | public class JwtUserDetailsServiceImpl extends BaseService implements UserDetailsService {
23 |
24 | @Autowired
25 | private UserMapper userMapper;
26 |
27 |
28 | @Autowired
29 | private RedisTemplate redisTemplate;
30 |
31 | @Override
32 | public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
33 |
34 |
35 | Map params = Maps.newHashMap();
36 | params.put("userName", username);
37 | User user = userMapper.selectUserAndAuthorities(params);
38 | if (user == null) {
39 | throw new UsernameNotFoundException(String.format("No user found with username '%s'.", username));
40 | } else {
41 | JwtUser userDetail = JwtUserFactory.create(user);
42 | return userDetail;
43 | }
44 | }
45 | }
46 |
--------------------------------------------------------------------------------
/car_admin/src/main/java/com/chinawiserv/admin/config/security/url/UrlAccessDecisionManager.java:
--------------------------------------------------------------------------------
1 | package com.chinawiserv.admin.config.security.url;
2 |
3 | import org.springframework.security.access.AccessDecisionManager;
4 | import org.springframework.security.access.AccessDeniedException;
5 | import org.springframework.security.access.ConfigAttribute;
6 | import org.springframework.security.authentication.InsufficientAuthenticationException;
7 | import org.springframework.security.core.Authentication;
8 | import org.springframework.security.core.GrantedAuthority;
9 | import org.springframework.security.web.FilterInvocation;
10 | import org.springframework.security.web.util.matcher.AntPathRequestMatcher;
11 | import org.springframework.stereotype.Service;
12 |
13 | import javax.servlet.http.HttpServletRequest;
14 | import java.util.Collection;
15 |
16 | /**
17 | * Created by sungang on 2017/10/24.
18 | */
19 | @Service
20 | public class UrlAccessDecisionManager implements AccessDecisionManager {
21 |
22 |
23 | @Override
24 | public void decide(Authentication authentication, Object object, Collection configAttributes) throws AccessDeniedException, InsufficientAuthenticationException {
25 | HttpServletRequest request = ((FilterInvocation) object).getHttpRequest();
26 | String url, method;
27 | Object principal = authentication.getPrincipal();
28 | if ("anonymousUser".equals(principal)
29 | || matchers("/images/**", request)
30 | || matchers("/js/**", request)
31 | || matchers("/css/**", request)
32 | || matchers("/fonts/**", request)
33 | || matchers("/api/", request)
34 | || matchers("/index.html", request)
35 | || matchers("/favicon.ico", request)
36 | || matchers("/api/login/**", request)) {
37 | return;
38 | } else {
39 | for (GrantedAuthority ga : authentication.getAuthorities()) {
40 | if (ga instanceof UrlGrantedAuthority) {
41 | UrlGrantedAuthority urlGrantedAuthority = (UrlGrantedAuthority) ga;
42 | url = urlGrantedAuthority.getPermissionUrl();
43 | method = urlGrantedAuthority.getMethod();
44 | if (matchers(url, request)) {
45 | if (method.equals(request.getMethod()) || "ALL".equals(method)) {
46 | return;
47 | }
48 | }
49 | }
50 | }
51 | }
52 | throw new AccessDeniedException("没有权限!");
53 | }
54 |
55 |
56 | @Override
57 | public boolean supports(ConfigAttribute attribute) {
58 | return true;
59 | }
60 |
61 | @Override
62 | public boolean supports(Class> clazz) {
63 | return true;
64 | }
65 |
66 |
67 | private boolean matchers(String url, HttpServletRequest request) {
68 | AntPathRequestMatcher matcher = new AntPathRequestMatcher(url);
69 | if (matcher.matches(request)) {
70 | return true;
71 | }
72 | return false;
73 | }
74 | }
75 |
--------------------------------------------------------------------------------
/car_admin/src/main/java/com/chinawiserv/admin/config/security/url/UrlConfigAttribute.java:
--------------------------------------------------------------------------------
1 | package com.chinawiserv.admin.config.security.url;
2 |
3 | import org.springframework.security.access.ConfigAttribute;
4 |
5 | import javax.servlet.http.HttpServletRequest;
6 |
7 | /**
8 | * Created by sungang on 2017/10/24.
9 | */
10 |
11 | public class UrlConfigAttribute implements ConfigAttribute {
12 |
13 | private final HttpServletRequest httpServletRequest;
14 |
15 | public UrlConfigAttribute(HttpServletRequest httpServletRequest) {
16 | this.httpServletRequest = httpServletRequest;
17 | }
18 |
19 |
20 | @Override
21 | public String getAttribute() {
22 | return null;
23 | }
24 |
25 | public HttpServletRequest getHttpServletRequest() {
26 | return httpServletRequest;
27 | }
28 | }
29 |
--------------------------------------------------------------------------------
/car_admin/src/main/java/com/chinawiserv/admin/config/security/url/UrlFilterSecurityInterceptor.java:
--------------------------------------------------------------------------------
1 | package com.chinawiserv.admin.config.security.url;
2 |
3 | import org.springframework.beans.factory.annotation.Autowired;
4 | import org.springframework.security.access.SecurityMetadataSource;
5 | import org.springframework.security.access.intercept.AbstractSecurityInterceptor;
6 | import org.springframework.security.access.intercept.InterceptorStatusToken;
7 | import org.springframework.security.web.FilterInvocation;
8 | import org.springframework.security.web.access.intercept.FilterInvocationSecurityMetadataSource;
9 | import org.springframework.stereotype.Service;
10 |
11 | import javax.servlet.*;
12 | import java.io.IOException;
13 |
14 | /**
15 | * Created by sungang on 2017/10/24.
16 | */
17 | @Service
18 | public class UrlFilterSecurityInterceptor extends AbstractSecurityInterceptor implements Filter {
19 | @Autowired
20 | private FilterInvocationSecurityMetadataSource securityMetadataSource;
21 |
22 | @Autowired
23 | public void setUrlAccessDecisionManager(UrlAccessDecisionManager urlAccessDecisionManager) {
24 | super.setAccessDecisionManager(urlAccessDecisionManager);
25 | }
26 |
27 |
28 | @Override
29 | public void init(FilterConfig filterConfig) throws ServletException {
30 |
31 | }
32 |
33 | @Override
34 | public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
35 |
36 | FilterInvocation fi = new FilterInvocation(request, response, chain);
37 | invoke(fi);
38 | }
39 |
40 |
41 | public void invoke(FilterInvocation fi) throws IOException, ServletException {
42 | //fi里面有一个被拦截的url
43 | //里面调用UrlMetadataSource的getAttributes(Object object)这个方法获取fi对应的所有权限
44 | //再调用UrlAccessDecisionManager的decide方法来校验用户的权限是否足够
45 | InterceptorStatusToken token = super.beforeInvocation(fi);
46 | try {
47 | //执行下一个拦截器
48 | fi.getChain().doFilter(fi.getRequest(), fi.getResponse());
49 | } finally {
50 | super.afterInvocation(token, null);
51 | }
52 | }
53 |
54 |
55 | @Override
56 | public void destroy() {
57 |
58 | }
59 |
60 | @Override
61 | public Class> getSecureObjectClass() {
62 | return FilterInvocation.class;
63 |
64 | }
65 |
66 | @Override
67 | public SecurityMetadataSource obtainSecurityMetadataSource() {
68 | return this.securityMetadataSource;
69 | }
70 | }
71 |
--------------------------------------------------------------------------------
/car_admin/src/main/java/com/chinawiserv/admin/config/security/url/UrlGrantedAuthority.java:
--------------------------------------------------------------------------------
1 | package com.chinawiserv.admin.config.security.url;
2 |
3 | import lombok.AllArgsConstructor;
4 | import lombok.Data;
5 | import org.springframework.security.core.GrantedAuthority;
6 |
7 | /**
8 | * Created by sungang on 2017/10/24.
9 | */
10 | @Data
11 | @AllArgsConstructor
12 | public class UrlGrantedAuthority implements GrantedAuthority {
13 |
14 | private String name;
15 | private String permissionUrl;
16 | private String method;
17 |
18 |
19 | @Override
20 | public String getAuthority() {
21 | return this.name + ";" + this.permissionUrl + ";" + this.method;
22 | }
23 | }
24 |
--------------------------------------------------------------------------------
/car_admin/src/main/java/com/chinawiserv/admin/config/security/url/UrlMetadataSourceService.java:
--------------------------------------------------------------------------------
1 | package com.chinawiserv.admin.config.security.url;
2 |
3 | import org.springframework.security.access.ConfigAttribute;
4 | import org.springframework.security.web.FilterInvocation;
5 | import org.springframework.security.web.access.intercept.FilterInvocationSecurityMetadataSource;
6 | import org.springframework.stereotype.Service;
7 |
8 | import javax.servlet.http.HttpServletRequest;
9 | import java.util.Collection;
10 | import java.util.HashSet;
11 | import java.util.Set;
12 |
13 |
14 | /**
15 | * Created by sungang on 2017/10/24.
16 | */
17 | @Service
18 | public class UrlMetadataSourceService implements FilterInvocationSecurityMetadataSource {
19 |
20 |
21 | @Override
22 | public Collection getAttributes(Object object) throws IllegalArgumentException {
23 | final HttpServletRequest request = ((FilterInvocation) object).getRequest();
24 | Set allAttributes = new HashSet<>();
25 | ConfigAttribute configAttribute = new UrlConfigAttribute(request);
26 | allAttributes.add(configAttribute);
27 | return allAttributes;
28 | }
29 |
30 | @Override
31 | public Collection getAllConfigAttributes() {
32 | return null;
33 | }
34 |
35 | @Override
36 | public boolean supports(Class> clazz) {
37 | return true;
38 | }
39 | }
40 |
--------------------------------------------------------------------------------
/car_admin/src/main/java/com/chinawiserv/admin/config/security/utils/TimeProvider.java:
--------------------------------------------------------------------------------
1 | package com.chinawiserv.admin.config.security.utils;
2 |
3 | import org.springframework.stereotype.Component;
4 |
5 | import java.io.Serializable;
6 | import java.util.Date;
7 |
8 | /**
9 | * Created by stephan on 04.07.17.
10 | */
11 | @Component
12 | public class TimeProvider implements Serializable {
13 |
14 | private static final long serialVersionUID = -3301695478208950415L;
15 |
16 | public Date now() {
17 | return new Date();
18 | }
19 | }
20 |
--------------------------------------------------------------------------------
/car_admin/src/main/java/com/chinawiserv/admin/controller/auth/AuthenticationController.java:
--------------------------------------------------------------------------------
1 | package com.chinawiserv.admin.controller.auth;
2 |
3 | import com.alibaba.fastjson.JSONObject;
4 | import com.chinawiserv.admin.config.security.JwtAuthenticationRequest;
5 | import com.chinawiserv.admin.config.security.JwtTokenUtil;
6 | import com.chinawiserv.admin.config.security.JwtUser;
7 | import com.chinawiserv.admin.mapper.UserMapper;
8 | import com.chinawiserv.admin.mapper.UserRoleMapper;
9 | import com.chinawiserv.admin.model.User;
10 | import com.chinawiserv.admin.model.UserRole;
11 | import com.chinawiserv.core.enums.GlobalErrorInfoEnum;
12 | import com.chinawiserv.core.exception.GlobalErrorInfoException;
13 | import com.chinawiserv.core.response.ResultBody;
14 | import com.chinawiserv.core.response.ResultGenerator;
15 | import com.google.common.collect.Maps;
16 | import org.springframework.beans.factory.annotation.Autowired;
17 | import org.springframework.beans.factory.annotation.Value;
18 | import org.springframework.data.redis.core.RedisTemplate;
19 | import org.springframework.mobile.device.Device;
20 | import org.springframework.security.authentication.AuthenticationManager;
21 | import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
22 | import org.springframework.security.core.Authentication;
23 | import org.springframework.security.core.AuthenticationException;
24 | import org.springframework.security.core.context.SecurityContextHolder;
25 | import org.springframework.security.core.userdetails.UserDetails;
26 | import org.springframework.security.core.userdetails.UserDetailsService;
27 | import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
28 | import org.springframework.web.bind.annotation.*;
29 |
30 | import javax.servlet.http.HttpServletRequest;
31 | import javax.servlet.http.HttpServletResponse;
32 | import java.util.Date;
33 | import java.util.Map;
34 |
35 | /**
36 | * Created by sungang on 2017/10/24.
37 | */
38 | @RestController
39 | @RequestMapping("/api/login")
40 | public class AuthenticationController {
41 |
42 |
43 | @Value("${jwt.header}")
44 | private String tokenHeader;
45 |
46 | @Autowired
47 | private JwtTokenUtil jwtTokenUtil;
48 |
49 | @Autowired
50 | private UserDetailsService userDetailsService;
51 |
52 | @Autowired
53 | private UserRoleMapper userRoleMapper;
54 | @Autowired
55 | private UserMapper userMapper;
56 |
57 | @Autowired
58 | private RedisTemplate redisTemplate;
59 |
60 |
61 | /**
62 | *
63 | * @param userToAdd
64 | * @return
65 | * @throws GlobalErrorInfoException
66 | */
67 | @PostMapping("register")
68 | public ResultBody register(User userToAdd) throws GlobalErrorInfoException {
69 | final String username = userToAdd.getUsername();
70 | Map params = Maps.newHashMap();
71 | params.put("userName", username);
72 | if (userMapper.selectUserAndAuthorities(params) != null) {
73 | return ResultGenerator.genFailResult(GlobalErrorInfoEnum.INTERNAL_SERVER_ERROR.getCode(),"改用户名已经存在!");
74 | }
75 | BCryptPasswordEncoder encoder = new BCryptPasswordEncoder();
76 | final String rawPassword = userToAdd.getPassword();
77 | userToAdd.setPassword(encoder.encode(rawPassword));
78 | userToAdd.setLastPasswordResetDate(new Date());
79 | userToAdd.setEmail("");
80 | userToAdd.setStatus(1);
81 | userMapper.insert(userToAdd);
82 |
83 |
84 | /**
85 | * 用户角色关系
86 | */
87 | UserRole userRole = new UserRole();
88 | userRole.setRoleId(userToAdd.getRoleId());
89 | userRole.setUserId(userToAdd.getId());
90 | userRoleMapper.insert(userRole);
91 |
92 |
93 | return ResultGenerator.genSuccessResult();
94 | }
95 |
96 |
97 |
98 | @Autowired
99 | private AuthenticationManager authenticationManager;
100 | @PostMapping
101 | public ResultBody createAuthenticationToken(@RequestBody JwtAuthenticationRequest authenticationRequest, Device device) throws AuthenticationException {
102 | UsernamePasswordAuthenticationToken upToken = new UsernamePasswordAuthenticationToken(authenticationRequest.getUsername(), authenticationRequest.getPassword());
103 | final Authentication authentication = authenticationManager.authenticate(upToken);
104 | SecurityContextHolder.getContext().setAuthentication(authentication);
105 | final UserDetails userDetails = userDetailsService.loadUserByUsername(authenticationRequest.getUsername());
106 | final String token = jwtTokenUtil.generateToken(userDetails, device);
107 |
108 | // Return the token
109 | JSONObject res = new JSONObject();
110 | res.put("access_token",token);
111 | res.put("authorities",userDetails.getAuthorities());
112 | return ResultGenerator.genSuccessResult(res);
113 | }
114 |
115 |
116 |
117 | @RequestMapping("403")
118 | public ResultBody access403(String url, HttpServletResponse response) throws AuthenticationException {
119 | response.setStatus(403);
120 | return ResultGenerator.genFailResult(GlobalErrorInfoEnum.INTERNAL_SERVER_ERROR.getCode(),"没有权限访问:" + url);
121 | }
122 |
123 | /**
124 | * @param request
125 | * @return
126 | */
127 | @GetMapping(value = "refresh")
128 | public ResultBody refreshAndGetAuthenticationToken(HttpServletRequest request) {
129 | String token = request.getHeader(tokenHeader);
130 | String username = jwtTokenUtil.getUsernameFromToken(token);
131 | JwtUser user = (JwtUser) userDetailsService.loadUserByUsername(username);
132 |
133 | if (jwtTokenUtil.canTokenBeRefreshed(token, user.getLastPasswordResetDate())) {
134 | String refreshedToken = jwtTokenUtil.refreshToken(token);
135 | return ResultGenerator.genSuccessResult(refreshedToken);
136 | } else {
137 | return ResultGenerator.genSuccessResult();
138 | }
139 | }
140 | }
141 |
--------------------------------------------------------------------------------
/car_admin/src/main/java/com/chinawiserv/admin/controller/test/MethodProtectedRestController.java:
--------------------------------------------------------------------------------
1 | package com.chinawiserv.admin.controller.test;
2 |
3 | import org.springframework.http.ResponseEntity;
4 | import org.springframework.security.access.prepost.PreAuthorize;
5 | import org.springframework.web.bind.annotation.RequestMapping;
6 | import org.springframework.web.bind.annotation.RequestMethod;
7 | import org.springframework.web.bind.annotation.RestController;
8 |
9 | @RestController
10 | @RequestMapping("api/protected")
11 | public class MethodProtectedRestController {
12 |
13 | /**
14 | * ADMIN 角色
15 | **/
16 | @RequestMapping(method = RequestMethod.GET)
17 | public ResponseEntity> getProtectedGreeting() {
18 | return ResponseEntity.ok("来自管理员的请求响应成功!");
19 | }
20 |
21 | }
--------------------------------------------------------------------------------
/car_admin/src/main/java/com/chinawiserv/admin/controller/test/Person.java:
--------------------------------------------------------------------------------
1 | package com.chinawiserv.admin.controller.test;
2 |
3 | /**
4 | * Created by stephan on 11.03.16.
5 | */
6 | public class Person {
7 | private String name;
8 | private String email;
9 |
10 | public Person() {
11 | }
12 |
13 | public Person(String name, String email) {
14 | this.name = name;
15 | this.email = email;
16 | }
17 |
18 | public String getName() {
19 | return name;
20 | }
21 |
22 | public void setName(String name) {
23 | this.name = name;
24 | }
25 |
26 | public String getEmail() {
27 | return email;
28 | }
29 |
30 | public void setEmail(String email) {
31 | this.email = email;
32 | }
33 | }
34 |
--------------------------------------------------------------------------------
/car_admin/src/main/java/com/chinawiserv/admin/controller/user/UserController.java:
--------------------------------------------------------------------------------
1 | package com.chinawiserv.admin.controller.user;
2 |
3 | import com.chinawiserv.admin.config.security.JwtTokenUtil;
4 | import com.chinawiserv.admin.config.security.JwtUser;
5 | import com.chinawiserv.admin.controller.test.Person;
6 | import com.chinawiserv.admin.model.User;
7 | import com.chinawiserv.core.response.ResultBody;
8 | import com.chinawiserv.core.response.ResultGenerator;
9 | import com.chinawiserv.core.web.controller.BaseCRUDController;
10 | import org.springframework.beans.factory.annotation.Autowired;
11 | import org.springframework.beans.factory.annotation.Value;
12 | import org.springframework.security.core.userdetails.UserDetailsService;
13 | import org.springframework.web.bind.annotation.*;
14 |
15 | import javax.servlet.http.HttpServletRequest;
16 | import java.util.ArrayList;
17 | import java.util.List;
18 |
19 | /**
20 | * Created by sungang on 2017/8/19.
21 | *
22 | * 在 @PreAuthorize 中我们可以利用内建的 SPEL 表达式:比如 'hasRole()' 来决定哪些用户有权访问。
23 | * 需注意的一点是 hasRole 表达式认为每个角色名字前都有一个前缀 'ROLE_'。所以这里的 'ADMIN' 其实在
24 | * 数据库中存储的是 'ROLE_ADMIN' 。这个 @PreAuthorize 可以修饰Controller也可修饰Controller
25 | */
26 | @RestController
27 | @RequestMapping("/api/user")
28 | public class UserController extends BaseCRUDController {
29 |
30 | @Value("${jwt.header}")
31 | private String tokenHeader;
32 |
33 | @Autowired
34 | private JwtTokenUtil jwtTokenUtil;
35 |
36 | @Autowired
37 | private UserDetailsService userDetailsService;
38 |
39 | @GetMapping
40 | public JwtUser getAuthenticatedUser(HttpServletRequest request) {
41 | String token = request.getHeader(tokenHeader);
42 | String username = jwtTokenUtil.getUsernameFromToken(token);
43 | JwtUser user = (JwtUser) userDetailsService.loadUserByUsername(username);
44 | return user;
45 | }
46 |
47 |
48 | private List persons = new ArrayList<>();
49 |
50 | private void add() {
51 | persons.add(new Person("Hello", "World"));
52 | persons.add(new Person("Foo", "Bar"));
53 | }
54 |
55 | private void clear() {
56 | persons.clear();
57 | }
58 |
59 | @RequestMapping(path = "/persons", method = RequestMethod.GET)
60 | public List getPersons() {
61 | return persons;
62 | }
63 |
64 | @RequestMapping(path = "/persons", method = RequestMethod.POST)
65 | public ResultBody addP() {
66 | add();
67 | return ResultGenerator.genSuccessResult();
68 | }
69 | @RequestMapping(path = "/persons", method = RequestMethod.DELETE)
70 | public ResultBody delP() {
71 | clear();
72 | return ResultGenerator.genSuccessResult();
73 | }
74 | @RequestMapping(path = "/persons/{name}", method = RequestMethod.GET)
75 | public Person getPerson(@PathVariable("name") String name) {
76 | return persons.stream()
77 | .filter(person -> name.equalsIgnoreCase(person.getName()))
78 | .findAny().orElse(null);
79 | }
80 |
81 |
82 | }
83 |
--------------------------------------------------------------------------------
/car_admin/src/main/java/com/chinawiserv/admin/mapper/PermissionMapper.java:
--------------------------------------------------------------------------------
1 | package com.chinawiserv.admin.mapper;
2 |
3 | import com.chinawiserv.admin.model.Permission;
4 | import com.chinawiserv.core.dao.mybatis.BaseMapper;
5 |
6 | /**
7 | * Created by sungang on 2017/10/24.
8 | */
9 | public interface PermissionMapper extends BaseMapper {
10 | }
11 |
--------------------------------------------------------------------------------
/car_admin/src/main/java/com/chinawiserv/admin/mapper/UserMapper.java:
--------------------------------------------------------------------------------
1 | package com.chinawiserv.admin.mapper;
2 |
3 | import com.chinawiserv.admin.model.User;
4 | import com.chinawiserv.core.dao.mybatis.BaseMapper;
5 |
6 | import java.util.Map;
7 |
8 | /**
9 | * Created by sungang on 2017/10/24.
10 | */
11 | public interface UserMapper extends BaseMapper {
12 |
13 | User selectUserAndAuthorities(Map params);
14 | }
15 |
--------------------------------------------------------------------------------
/car_admin/src/main/java/com/chinawiserv/admin/mapper/UserRoleMapper.java:
--------------------------------------------------------------------------------
1 | package com.chinawiserv.admin.mapper;
2 |
3 | import com.chinawiserv.admin.model.UserRole;
4 | import com.chinawiserv.core.dao.mybatis.BaseMapper;
5 |
6 | /**
7 | * Created by sungang on 2017/10/24.
8 | */
9 | public interface UserRoleMapper extends BaseMapper {
10 | }
11 |
--------------------------------------------------------------------------------
/car_admin/src/main/java/com/chinawiserv/admin/model/Permission.java:
--------------------------------------------------------------------------------
1 | package com.chinawiserv.admin.model;
2 |
3 | import com.chinawiserv.core.model.BaseModel;
4 | import lombok.Data;
5 | import lombok.ToString;
6 |
7 | import javax.persistence.*;
8 | import java.util.Date;
9 |
10 | /**
11 | * Created by sungang on 2017/10/24.
12 | */
13 | @Table(name = "sys_user")
14 | @Data
15 | @ToString
16 | public class Permission extends BaseModel {
17 |
18 |
19 | @Id
20 | @GeneratedValue(strategy = GenerationType.IDENTITY)
21 | private Long id;
22 |
23 |
24 | private String name;
25 |
26 | private Long pid;
27 |
28 | private String method;
29 |
30 | @Column(name = "permission_url")
31 | private String permissionUrl;
32 |
33 | private String description;
34 |
35 | @Column(name = "create_time")
36 | private Date createTime;
37 | }
38 |
--------------------------------------------------------------------------------
/car_admin/src/main/java/com/chinawiserv/admin/model/User.java:
--------------------------------------------------------------------------------
1 | package com.chinawiserv.admin.model;
2 |
3 | import com.chinawiserv.core.model.BaseModel;
4 | import lombok.Data;
5 | import lombok.ToString;
6 |
7 | import javax.persistence.*;
8 | import java.util.Date;
9 | import java.util.List;
10 |
11 | /**
12 | * Created by sungang on 2017/10/24.
13 | */
14 | @Table(name = "sys_user")
15 | @Data
16 | @ToString
17 | public class User extends BaseModel{
18 |
19 | @Id
20 | @GeneratedValue(strategy = GenerationType.IDENTITY)
21 | private Long id;
22 |
23 | private String username;
24 |
25 | private String password;
26 |
27 | private String name;
28 |
29 | private String email;
30 |
31 | private Integer status;
32 |
33 | private String remark;
34 |
35 | @Column(name = "last_password_reset_date")
36 | private Date lastPasswordResetDate;
37 |
38 | @Transient
39 | private List authorities;
40 |
41 | @Transient
42 | private Long roleId;
43 | }
44 |
--------------------------------------------------------------------------------
/car_admin/src/main/java/com/chinawiserv/admin/model/UserRole.java:
--------------------------------------------------------------------------------
1 | package com.chinawiserv.admin.model;
2 |
3 | import com.chinawiserv.core.model.BaseModel;
4 | import lombok.Data;
5 | import lombok.ToString;
6 |
7 | import javax.persistence.*;
8 |
9 | /**
10 | * Created by sungang on 2017/10/24.
11 | */
12 | @Table(name = "sys_user")
13 | @Data
14 | @ToString
15 | public class UserRole extends BaseModel {
16 |
17 |
18 | @Id
19 | @GeneratedValue(strategy = GenerationType.IDENTITY)
20 | private Long id;
21 |
22 |
23 |
24 | @Column(name = "user_id")
25 | private Long userId;
26 |
27 |
28 | @Column(name = "role_id")
29 | private Long roleId;
30 | }
31 |
--------------------------------------------------------------------------------
/car_admin/src/main/java/com/chinawiserv/admin/service/sys/UserService.java:
--------------------------------------------------------------------------------
1 | package com.chinawiserv.admin.service.sys;
2 |
3 | import com.chinawiserv.admin.model.User;
4 | import com.chinawiserv.core.service.IService;
5 |
6 | /**
7 | * Created by sungang on 2017/10/24.
8 | */
9 | public interface UserService extends IService {
10 | }
11 |
--------------------------------------------------------------------------------
/car_admin/src/main/java/com/chinawiserv/admin/service/sys/UserServiceImpl.java:
--------------------------------------------------------------------------------
1 | package com.chinawiserv.admin.service.sys;
2 |
3 | import com.chinawiserv.admin.model.User;
4 | import com.chinawiserv.core.service.BaseService;
5 | import lombok.extern.slf4j.Slf4j;
6 | import org.springframework.stereotype.Service;
7 |
8 | /**
9 | * Created by sungang on 20
10 | * 17/10/24.
11 | */
12 | @Service
13 | @Slf4j
14 | public class UserServiceImpl extends BaseService implements UserService {
15 | }
16 |
--------------------------------------------------------------------------------
/car_admin/src/main/resources/application-dev.properties:
--------------------------------------------------------------------------------
1 |
2 | #修改启动端口
3 | server.port=8021
4 | #修改访问路径 默认是 /
5 | server.context-path=/
6 | #用户会话session过期时间 以秒为单位
7 | #server.session-timeout=
8 | #配置Tomcat编码 默认是UTF-8
9 | server.tomcat.uri-encoding = UTF-8
10 | #Tomcat是否开启压缩 默认是关闭 off
11 | server.tomcat.compression = off
12 | server.tomcat.max-threads=800
13 | server.tomcat.basedir = target/tomcat/admin
14 | # session 超时间 此设置将自动与 Redis session超时一致 单位:s 前提 使用spring boot : run
15 | #server.session.timeout = 30
16 |
17 |
18 |
19 | # 是否显示异常信息
20 | show-exception = true
21 |
22 | ########################### JWT And Captcha#############################
23 | jwt.header = Authorization
24 | jwt.secret = mySecret
25 | jwt.expiration = 604800
26 |
27 | jwt.captcha-UUID-mark=Captcha-UUID-Mark
28 | ########################### JWT And Captcha#############################
29 |
30 |
31 |
32 |
33 | # 使用 MD5 作为版本号
34 | # 是否开启内容版本策略,默认为false
35 | #spring.resources.chain.strategy.content.enable=true
36 | #spring.resources.chain.strategy.content.paths=/**
37 |
38 | #日志
39 | #logging.file=log.log
40 | #logging.level.org.springframework.web=INFO
41 | #设置true 可以查看boot运行 已启用的自动配置
42 | #Positive matches:表示已启用的配置
43 | #Negative matches:表示未启用的配置
44 | #debug=true
45 | #日志
46 | log.path=/Users/sungang/Documents/logs/car_admin
47 | log.level=INFO
48 | #日志最多保留天数
49 | log.maxHistory=1
50 | #会检查终端是否支持ANSI,是的话就采用彩色输出
51 | spring.output.ansi.enabled = DETECT
52 |
53 |
54 | ########################################################
55 | ### i18n setting.
56 | ########################################################
57 | #指定message的basename,多个以逗号分隔,如果不加包名的话,默认从classpath路径开始,默认: messages
58 | spring.messages.basename=i18n/messages
59 | #设定加载的资源文件缓存失效时间,-1的话为永不过期,默认为-1
60 | spring.messages.cache-seconds= 3600
61 | #设定Message bundles的编码,默认: UTF-8
62 | #spring.messages.encoding=UTF-8
63 |
64 |
65 | ### RabbitMQ Start
66 | #spring.rabbitmq.host= 43.254.3.72
67 | #spring.rabbitmq.port=5672
68 | #spring.rabbitmq.username=admin
69 | #spring.rabbitmq.password=123456
70 | #spring.rabbitmq.virtual-host=/
71 | ### RabbitMQ End
72 |
73 |
74 | ############################### Redis Start ######################################
75 | #spring.session.store-type=redis
76 | # Redis数据库索引(默认为0)
77 | spring.redis.database=0
78 | # Redis服务器地址
79 | spring.redis.host=43.254.3.68
80 | #spring.redis.host=43.254.3.72
81 | #spring.redis.cluster.nodes = 43.254.3.68
82 | # Login password of the redis server.
83 | # Redis服务器连接密码(默认为空)
84 | spring.redis.password=Chinawiservqz#
85 | #spring.redis.password=Dehui2017
86 | # Redis服务器连接端口
87 | spring.redis.port=3697
88 | #spring.redis.port=6379
89 | # 连接池中的最大空闲连接
90 | spring.redis.pool.max-idle=8
91 | # 连接池中的最小空闲连接
92 | spring.redis.pool.min-idle=5
93 | # 连接池最大连接数(使用负值表示没有限制)
94 | spring.redis.pool.max-active=8
95 | # 连接池最大阻塞等待时间(使用负值表示没有限制)
96 | spring.redis.pool.max-wait=-1
97 | # Name of Redis server.
98 | #spring.redis.sentinel.master=
99 | # Comma-separated list of host:port pairs.
100 | #spring.redis.sentinel.nodes=
101 | # 连接超时时间(毫秒)
102 | spring.redis.timeout=3600
103 |
104 | ############################### Redis End ######################################
105 |
106 |
107 | ########################################################
108 | ### Mybatis Setting
109 | ########################################################
110 | #mybatis
111 | mybatis.type-aliases-package=com.chinawiserv.admin.model
112 | mybatis.mapper-locations=classpath:mapper/*.xml
113 | mybatis.config-location=classpath:mybatis/mybatis-config.xml
114 | #mapper
115 | #mappers 多个接口时逗号隔开
116 | mapper.mappers=com.chinawiserv.core.dao.mybatis.BaseMapper
117 | mapper.not-empty=false
118 | mapper.identity=MYSQL
119 | #pagehelper
120 | pagehelper.helperDialect=mysql
121 | pagehelper.reasonable=true
122 | pagehelper.supportMethodsArguments=true
123 | pagehelper.params=count=countSql
124 |
125 |
126 | # 数据库访问配置
127 | # 主数据源,默认的
128 | spring.datasource.type=com.alibaba.druid.pool.DruidDataSource
129 | spring.datasource.driverClassName=com.mysql.jdbc.Driver
130 | spring.datasource.url=jdbc:mysql://localhost:3306/skcar?autoReconnect=true&useUnicode=true&characterEncoding=utf-8
131 | spring.datasource.username=root
132 | spring.datasource.password=123456
133 |
134 |
135 | # 下面为连接池的补充设置,应用到上面所有数据源中
136 | # 初始化大小,最小,最大
137 | spring.datasource.initialSize=5
138 | spring.datasource.minIdle=5
139 | spring.datasource.maxActive=20
140 | # 配置获取连接等待超时的时间
141 | spring.datasource.maxWait=60000
142 | # 配置间隔多久才进行一次检测,检测需要关闭的空闲连接,单位是毫秒
143 | spring.datasource.timeBetweenEvictionRunsMillis=60000
144 | # 配置一个连接在池中最小生存的时间,单位是毫秒
145 | spring.datasource.minEvictableIdleTimeMillis=300000
146 | # 配置一个连接在池中最小生存的时间,单位是毫秒
147 | spring.datasource.validationQuery=SELECT 'x'
148 | spring.datasource.testWhileIdle=true
149 | spring.datasource.testOnBorrow=false
150 | spring.datasource.testOnReturn=false
151 | # 打开PSCache,并且指定每个连接上PSCache的大小
152 | spring.datasource.poolPreparedStatements=true
153 | spring.datasource.maxPoolPreparedStatementPerConnectionSize=20
154 | # 配置监控统计拦截的filters,去掉后监控界面sql无法统计,'wall'用于防火墙
155 | spring.datasource.filters=wall,stat
156 | # 通过connectProperties属性来打开mergeSql功能;慢SQL记录
157 | spring.datasource.connectionProperties=druid.stat.mergeSql=true;druid.stat.slowSqlMillis=5000
158 | # 合并多个DruidDataSource的监控数据
159 | #spring.datasource.useGlobalDataSourceStat=true
160 |
161 |
162 | #Http Encoding default UTF-8
163 | spring.http.encoding.charset=UTF-8
164 | #设置forceEncoding 默认是true
165 | spring.http.encoding.force=true
166 | #默认支持文件上传.
167 | spring.http.multipart.enabled=true
168 | #支持文件写入磁盘.
169 | spring.http.multipart.file-size-threshold=0
170 | # 上传文件的临时目录
171 | #spring.http.multipart.location=
172 | # 最大支持文件大小
173 | spring.http.multipart.max-file-size=8Mb
174 | # 最大支持请求大小
175 | spring.http.multipart.max-request-size=10Mb
176 |
177 |
178 |
179 |
180 |
181 |
--------------------------------------------------------------------------------
/car_admin/src/main/resources/application-prod.properties:
--------------------------------------------------------------------------------
1 |
2 | #修改启动端口
3 | server.port=8021
4 | #修改访问路径 默认是 /
5 | server.context-path=/
6 | #用户会话session过期时间 以秒为单位
7 | #server.session-timeout=
8 | #配置Tomcat编码 默认是UTF-8
9 | server.tomcat.uri-encoding = UTF-8
10 | server.tomcat.max-threads=800
11 | server.tomcat.basedir = target/tomcat/admin
12 | # session 超时间 此设置将自动与 Redis session超时一致 单位:s 前提 使用spring boot : run
13 | #server.session.timeout = 30
14 |
15 |
16 | # 是否显示异常信息
17 | show-exception = true
18 |
19 | ########################### JWT And Captcha#############################
20 | jwt.header = Authorization
21 | jwt.secret = mySecret
22 | jwt.expiration = 604800
23 |
24 | jwt.Captcha-UUID-code=Captcha-UUID-code
25 | ########################### JWT And Captcha#############################
26 |
27 |
28 | # 设置静态资源的存放地址
29 | #spring.resources.static-locations=classpath:/resources
30 |
31 | # 是否开启缓存,默认为: true
32 | spring.resources.chain.cache=true
33 |
34 | #设定资源的缓存时效,以秒为单位.
35 | spring.resources.cache-period = 1
36 |
37 | # 开启 gzip
38 | spring.resources.chain.gzipped=true
39 |
40 | # 指定版本号
41 | # 是否开启固定的版本策略,默认为false
42 | spring.resources.chain.strategy.fixed.enabled=true
43 | # 指定要应用版本策略的路径,多个以逗号分隔
44 | spring.resources.chain.strategy.fixed.paths=/static
45 | # 指定版本策略使用的版本号
46 | spring.resources.chain.strategy.fixed.version=1.0.0
47 |
48 |
49 | # 是否开启h5应用的cache manifest重写,默认为: false
50 | spring.resources.chain.html-application-cache = true
51 |
52 |
53 |
54 |
55 | #日志
56 | #logging.file=log.log
57 | #logging.level.org.springframework.web=INFO
58 | #设置true 可以查看boot运行 已启用的自动配置
59 | #Positive matches:表示已启用的配置
60 | #Negative matches:表示未启用的配置
61 | #debug=true
62 | #日志
63 | log.path=/chinawiserv/application/logs/art_api
64 | log.level=INFO
65 | #日志最多保留天数
66 | log.maxHistory=10
67 | #会检查终端是否支持ANSI,是的话就采用彩色输出
68 | spring.output.ansi.enabled = DETECT
69 |
70 |
71 | ########################################################
72 | ### i18n setting.
73 | ########################################################
74 | #指定message的basename,多个以逗号分隔,如果不加包名的话,默认从classpath路径开始,默认: messages
75 | spring.messages.basename=i18n/messages
76 | #设定加载的资源文件缓存失效时间,-1的话为永不过期,默认为-1
77 | spring.messages.cache-seconds= 3600
78 | #设定Message bundles的编码,默认: UTF-8
79 | #spring.messages.encoding=UTF-8
80 |
81 |
82 | ### RabbitMQ Start
83 | #spring.rabbitmq.host= 43.254.3.72
84 | #spring.rabbitmq.port=5672
85 | #spring.rabbitmq.username=admin
86 | #spring.rabbitmq.password=123456
87 | #spring.rabbitmq.virtual-host=/
88 | ### RabbitMQ End
89 |
90 | ############################### Redis Start ######################################
91 | #spring.session.store-type=redis
92 | # Redis数据库索引(默认为0)
93 | spring.redis.database=0
94 | # Redis服务器地址
95 | spring.redis.host=localhost
96 | # Login password of the redis server.
97 | # Redis服务器连接密码(默认为空)
98 | spring.redis.password=Dehui2017
99 | # Redis服务器连接端口
100 | spring.redis.port=6379
101 | # 连接池中的最大空闲连接
102 | spring.redis.pool.max-idle=8
103 | # 连接池中的最小空闲连接
104 | spring.redis.pool.min-idle=5
105 | # 连接池最大连接数(使用负值表示没有限制)
106 | spring.redis.pool.max-active=8
107 | # 连接池最大阻塞等待时间(使用负值表示没有限制)
108 | spring.redis.pool.max-wait=-1
109 | # Name of Redis server.
110 | #spring.redis.sentinel.master=
111 | # Comma-separated list of host:port pairs.
112 | #spring.redis.sentinel.nodes=
113 | # 连接超时时间(毫秒)
114 | spring.redis.timeout=3600
115 |
116 | ############################### Redis End ######################################
117 |
118 |
119 |
120 | ########################################################
121 | ### Mybatis Setting
122 | ########################################################
123 | #mybatis
124 | mybatis.type-aliases-package=com.chinawiserv.model
125 | mybatis.mapper-locations=classpath:mapper/*.xml
126 | #mybatis.config-location=classpath:mybatis/mybatis-config.xml
127 | #mapper
128 | #mappers 多个接口时逗号隔开
129 | mapper.mappers=com.chinawiserv.core.dao.mybatis.BaseMapper
130 | mapper.not-empty=false
131 | mapper.identity=MYSQL
132 | #pagehelper
133 | pagehelper.helperDialect=mysql
134 | pagehelper.reasonable=true
135 | pagehelper.supportMethodsArguments=true
136 | pagehelper.params=count=countSql
137 |
138 |
139 | # 数据库访问配置
140 | # 主数据源,默认的
141 | spring.datasource.type=com.alibaba.druid.pool.DruidDataSource
142 | spring.datasource.driverClassName=com.mysql.jdbc.Driver
143 | spring.datasource.url=jdbc:mysql://localhost:3306/spar?autoReconnect=true&useUnicode=true&characterEncoding=utf-8
144 | spring.datasource.username=root
145 | spring.datasource.password=Dehui2017
146 |
147 |
148 | # 下面为连接池的补充设置,应用到上面所有数据源中
149 | # 初始化大小,最小,最大
150 | spring.datasource.initialSize=5
151 | spring.datasource.minIdle=5
152 | spring.datasource.maxActive=20
153 | # 配置获取连接等待超时的时间
154 | spring.datasource.maxWait=60000
155 | # 配置间隔多久才进行一次检测,检测需要关闭的空闲连接,单位是毫秒
156 | spring.datasource.timeBetweenEvictionRunsMillis=60000
157 | # 配置一个连接在池中最小生存的时间,单位是毫秒
158 | spring.datasource.minEvictableIdleTimeMillis=300000
159 | # 配置一个连接在池中最小生存的时间,单位是毫秒
160 | spring.datasource.validationQuery=SELECT 'x'
161 | spring.datasource.testWhileIdle=true
162 | spring.datasource.testOnBorrow=false
163 | spring.datasource.testOnReturn=false
164 | # 打开PSCache,并且指定每个连接上PSCache的大小
165 | spring.datasource.poolPreparedStatements=true
166 | spring.datasource.maxPoolPreparedStatementPerConnectionSize=20
167 | # 配置监控统计拦截的filters,去掉后监控界面sql无法统计,'wall'用于防火墙
168 | spring.datasource.filters=wall,stat
169 | # 通过connectProperties属性来打开mergeSql功能;慢SQL记录
170 | spring.datasource.connectionProperties=druid.stat.mergeSql=true;druid.stat.slowSqlMillis=5000
171 | # 合并多个DruidDataSource的监控数据
172 | #spring.datasource.useGlobalDataSourceStat=true
173 |
174 |
175 | #Http Encoding default UTF-8
176 | spring.http.encoding.charset=UTF-8
177 | #设置forceEncoding 默认是true
178 | spring.http.encoding.force=true
179 | #默认支持文件上传.
180 | spring.http.multipart.enabled=true
181 | #支持文件写入磁盘.
182 | spring.http.multipart.file-size-threshold=0
183 | # 上传文件的临时目录
184 | #spring.http.multipart.location=
185 | # 最大支持文件大小
186 | spring.http.multipart.max-file-size=8Mb
187 | # 最大支持请求大小
188 | spring.http.multipart.max-request-size=10Mb
189 |
190 |
191 |
192 |
193 | ############################## Swagger-UI #################################
194 | #标题
195 | swagger.title=art_api
196 | #描述
197 | swagger.description=art_api 1.x
198 | #版本
199 | swagger.version=0.1
200 | #许可证URL
201 | swagger.license=
202 | #服务条款URL
203 | swagger.licenseUrl=
204 | #
205 | swagger.termsOfServiceUrl=
206 | #维护人
207 | swagger.contact.name=Williamsun
208 | #维护人URL
209 | swagger.contact.url=https://github.com/aillamsun
210 | #维护人邮箱
211 | swagger.contact.email=1120sungang@gmail.com
212 | #扫描的基础包,默认:全扫描
213 | swagger.base-package=com.chinawiserv.api.controller
214 | #需要处理的基础URL规则,默认:/**
215 | swagger.base-path=/**
216 | #需要排除的URL规则,默认:空
217 | swagger.exclude-path=/error, /dashboard/**, /auth/**
218 | ############################## Swagger-UI #################################
--------------------------------------------------------------------------------
/car_admin/src/main/resources/application.properties:
--------------------------------------------------------------------------------
1 | # dev 开发环境
2 | # prod 生产环境
3 | spring.profiles.active=dev
4 |
5 |
6 | #http://localhost:port/info
7 | info.build.artifact=@project.artifactId@
8 | info.build.name=@project.name@
9 | info.build.description=@project.description@
10 | info.build.version=@project.version@
11 |
12 |
--------------------------------------------------------------------------------
/car_admin/src/main/resources/i18n/messages.properties:
--------------------------------------------------------------------------------
1 | # 认证 授权
2 | auth.success=认证注册成功
3 | auth.error=认证注册信息不通过
4 | auth.before=请先注册认证
5 | app_key.error=Token不正确
6 | sign.error=sign或者签名参数不正确
7 | secrity_key.exist=该app_key已经注册
8 | auth.regiter.error=注册{0}认证信{1}息失败
9 |
10 |
11 |
12 |
13 |
14 |
--------------------------------------------------------------------------------
/car_admin/src/main/resources/i18n/messages_en_US.properties:
--------------------------------------------------------------------------------
1 | welcome = welcome to login to alibaba website(English)
--------------------------------------------------------------------------------
/car_admin/src/main/resources/i18n/messages_zh_CN.properties:
--------------------------------------------------------------------------------
1 | welcome = \u6b22\u8fce\u4f60\u767b\u5f55\u5230 \u963f\u91cc\u5df4\u5df4 \u7f51\u7ad9\uff08\u4e2d\u6587\uff09
--------------------------------------------------------------------------------
/car_admin/src/main/resources/mapper/UserMapper.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
40 |
--------------------------------------------------------------------------------
/car_admin/src/main/resources/mybatis/mybatis-config.xml:
--------------------------------------------------------------------------------
1 |
2 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
--------------------------------------------------------------------------------
/car_admin/src/main/resources/skcar.sql:
--------------------------------------------------------------------------------
1 | /*
2 | Navicat Premium Data Transfer
3 |
4 | Source Server : localhost
5 | Source Server Type : MySQL
6 | Source Server Version : 50717
7 | Source Host : localhost
8 | Source Database : skcar
9 |
10 | Target Server Type : MySQL
11 | Target Server Version : 50717
12 | File Encoding : utf-8
13 |
14 | Date: 04/09/2018 10:22:18 AM
15 | */
16 |
17 | SET NAMES utf8mb4;
18 | SET FOREIGN_KEY_CHECKS = 0;
19 |
20 | -- ----------------------------
21 | -- Table structure for `sys_permission`
22 | -- ----------------------------
23 | DROP TABLE IF EXISTS `sys_permission`;
24 | CREATE TABLE `sys_permission` (
25 | `id` bigint(20) NOT NULL,
26 | `name` varchar(255) DEFAULT NULL,
27 | `pid` bigint(20) DEFAULT NULL,
28 | `method` varchar(50) DEFAULT NULL COMMENT '请求方法',
29 | `permission_url` varchar(255) DEFAULT NULL COMMENT '授权链接',
30 | `description` varchar(255) DEFAULT NULL,
31 | `create_time` datetime DEFAULT NULL,
32 | PRIMARY KEY (`id`)
33 | ) ENGINE=InnoDB DEFAULT CHARSET=utf8 ROW_FORMAT=COMPACT COMMENT='系统权限表';
34 |
35 | -- ----------------------------
36 | -- Records of `sys_permission`
37 | -- ----------------------------
38 | BEGIN;
39 | INSERT INTO `sys_permission` VALUES ('1', 'ADMIN', null, 'ALL', '/api/**', '项目最大权限', '2017-10-24 15:49:04'), ('2', 'USER_ALL', null, 'ALL', '/api/user/**', '用户所有权限', '2017-10-24 15:49:01'), ('3', 'USER_GET', null, 'GET', '/api/user/**', '获取单个用户', '2017-10-24 14:44:24'), ('4', 'USER_PUT', null, 'PUT', '/api/user/**', '修改用户', '2017-10-24 14:45:22'), ('5', 'USER_ADD', null, 'POST', '/api/user/**', '添加用户', '2017-10-24 14:46:03'), ('6', 'USER_ DELETE', null, 'DELETE', '/api/user/**', '删除用户', '2017-10-24 15:49:46');
40 | COMMIT;
41 |
42 | -- ----------------------------
43 | -- Table structure for `sys_role`
44 | -- ----------------------------
45 | DROP TABLE IF EXISTS `sys_role`;
46 | CREATE TABLE `sys_role` (
47 | `id` bigint(20) NOT NULL AUTO_INCREMENT,
48 | `name` varchar(45) NOT NULL COMMENT '角色名称',
49 | `role` varchar(45) DEFAULT NULL,
50 | `description` varchar(45) DEFAULT NULL,
51 | `is_all` int(11) DEFAULT '0' COMMENT '是否是全选 0 否 1 是',
52 | `create_time` datetime DEFAULT NULL,
53 | `create_user_id` bigint(20) DEFAULT NULL COMMENT '创建人id',
54 | `status` int(45) DEFAULT NULL COMMENT '0 不可用 1 可用',
55 | PRIMARY KEY (`id`)
56 | ) ENGINE=InnoDB AUTO_INCREMENT=21 DEFAULT CHARSET=utf8 ROW_FORMAT=COMPACT COMMENT='角色表';
57 |
58 | -- ----------------------------
59 | -- Records of `sys_role`
60 | -- ----------------------------
61 | BEGIN;
62 | INSERT INTO `sys_role` VALUES ('1', 'Admin', 'admin', 'admin', '1', '2017-10-24 11:30:03', '1', '1'), ('2', 'User_All', 'User_All', '用户所有权限', '1', '2017-10-24 11:30:19', '1', '1'), ('3', 'User_A_G', 'User_A_G', '用户添加查询权限', '1', '2017-10-24 16:27:24', '1', '1'), ('4', 'User_A_U_G', 'User_A_U_G', '用户添加修改查询权限', '1', '2017-10-24 17:20:05', '1', '1');
63 | COMMIT;
64 |
65 | -- ----------------------------
66 | -- Table structure for `sys_role_permission`
67 | -- ----------------------------
68 | DROP TABLE IF EXISTS `sys_role_permission`;
69 | CREATE TABLE `sys_role_permission` (
70 | `id` bigint(20) NOT NULL,
71 | `role_id` bigint(20) NOT NULL,
72 | `permission_id` bigint(20) NOT NULL,
73 | PRIMARY KEY (`id`)
74 | ) ENGINE=InnoDB DEFAULT CHARSET=utf8 ROW_FORMAT=COMPACT;
75 |
76 | -- ----------------------------
77 | -- Records of `sys_role_permission`
78 | -- ----------------------------
79 | BEGIN;
80 | INSERT INTO `sys_role_permission` VALUES ('1', '1', '1'), ('2', '2', '2'), ('3', '3', '3'), ('4', '4', '4'), ('5', '4', '5'), ('6', '3', '5'), ('7', '4', '3');
81 | COMMIT;
82 |
83 | -- ----------------------------
84 | -- Table structure for `sys_user`
85 | -- ----------------------------
86 | DROP TABLE IF EXISTS `sys_user`;
87 | CREATE TABLE `sys_user` (
88 | `id` bigint(20) NOT NULL AUTO_INCREMENT,
89 | `username` varchar(255) NOT NULL COMMENT '用户名',
90 | `password` varchar(255) NOT NULL COMMENT '用户密码',
91 | `name` varchar(255) DEFAULT NULL COMMENT '用户姓名',
92 | `sex` int(2) DEFAULT NULL COMMENT '性别 1 男 2 女',
93 | `email` varchar(255) DEFAULT NULL COMMENT '邮箱',
94 | `title` varchar(255) DEFAULT NULL COMMENT '职称',
95 | `phone` varchar(11) NOT NULL COMMENT '电话',
96 | `organ_id` bigint(20) NOT NULL COMMENT '公司id',
97 | `dept_id` bigint(20) NOT NULL COMMENT '部门id',
98 | `position` varchar(30) DEFAULT NULL COMMENT '职位',
99 | `job` varchar(30) DEFAULT NULL COMMENT '岗位',
100 | `create_time` datetime DEFAULT NULL COMMENT '创建时间',
101 | `create_user_id` bigint(20) DEFAULT NULL COMMENT '创建人',
102 | `status` int(4) DEFAULT '1' COMMENT '1 正常 2 锁定 3 删除',
103 | `remark` varchar(255) DEFAULT NULL COMMENT '备注',
104 | `last_password_reset_date` datetime DEFAULT NULL,
105 | PRIMARY KEY (`id`)
106 | ) ENGINE=InnoDB AUTO_INCREMENT=7 DEFAULT CHARSET=utf8 ROW_FORMAT=COMPACT;
107 |
108 | -- ----------------------------
109 | -- Records of `sys_user`
110 | -- ----------------------------
111 | BEGIN;
112 | INSERT INTO `sys_user` VALUES ('1', 'admin', '0DPiKuNIrrVmD8IUCuw1hQxNqZc=', null, null, null, null, '13076061657', '1', '1', null, null, '2017-10-24 11:31:12', '1', '1', null, '2017-10-24 12:59:14'), ('2', 'user_all', 'fEqNCco3Yq9h5ZUglD3CZJT4lBs=', null, null, null, null, '307071768', '1', '1', null, null, '2017-10-24 11:32:12', '1', '1', null, '2017-10-24 12:59:17'), ('3', 'disabled', 'fEqNCco3Yq9h5ZUglD3CZJT4lBs=', null, null, null, null, '111', '1', '1', null, null, '2017-10-24 11:32:46', '1', '0', null, '2017-10-24 12:59:21'), ('5', 'user_a_g', 'fEqNCco3Yq9h5ZUglD3CZJT4lBs=', null, null, null, null, '1', '1', '1', null, null, '2017-10-24 16:24:58', null, '1', null, null), ('6', 'user_a_u_g', 'fEqNCco3Yq9h5ZUglD3CZJT4lBs=', null, null, null, null, '1', '1', '1', null, null, '2017-10-24 16:25:27', null, '1', null, null);
113 | COMMIT;
114 |
115 | -- ----------------------------
116 | -- Table structure for `sys_user_role`
117 | -- ----------------------------
118 | DROP TABLE IF EXISTS `sys_user_role`;
119 | CREATE TABLE `sys_user_role` (
120 | `id` bigint(20) NOT NULL,
121 | `user_id` bigint(20) NOT NULL,
122 | `role_id` bigint(20) NOT NULL,
123 | PRIMARY KEY (`id`)
124 | ) ENGINE=InnoDB DEFAULT CHARSET=utf8 ROW_FORMAT=COMPACT COMMENT='用户角色表';
125 |
126 | -- ----------------------------
127 | -- Records of `sys_user_role`
128 | -- ----------------------------
129 | BEGIN;
130 | INSERT INTO `sys_user_role` VALUES ('1', '1', '1'), ('2', '2', '2'), ('3', '3', '2'), ('4', '5', '3'), ('5', '6', '4');
131 | COMMIT;
132 |
133 | SET FOREIGN_KEY_CHECKS = 1;
134 |
--------------------------------------------------------------------------------
/car_admin/src/main/resources/static/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | JWT Spring Security Demo
6 |
7 |
8 |
10 |
11 |
12 |
14 |
15 |
16 |
17 |
18 |
Spring boot For JWT And Spring Security Example!
19 |
20 |
Not logged in!
21 |
22 |
23 |
24 |
25 |
26 |
登录
27 |
28 |
51 |
52 |
53 |
54 |
55 |
56 |
认证用户信息
57 |
58 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 |
75 |
响应:
76 |
77 |
80 |
81 |
82 |
83 |
84 |
85 |
86 |
87 |
88 |
Token 信息
89 |
90 |
91 |
92 |
93 |
94 |
95 |
96 |
110 |
111 |
113 |
114 |
117 |
118 |
119 |
120 |
--------------------------------------------------------------------------------
/car_admin/src/main/resources/static/js/libs/jwt-decode.min.js:
--------------------------------------------------------------------------------
1 | !function a(b,c,d){function e(g,h){if(!c[g]){if(!b[g]){var i="function"==typeof require&&require;if(!h&&i)return i(g,!0);if(f)return f(g,!0);var j=new Error("Cannot find module '"+g+"'");throw j.code="MODULE_NOT_FOUND",j}var k=c[g]={exports:{}};b[g][0].call(k.exports,function(a){var c=b[g][1][a];return e(c?c:a)},k,k.exports,a,b,c,d)}return c[g].exports}for(var f="function"==typeof require&&require,g=0;g>(-2*g&6)):0)e=f.indexOf(e);return i}var f="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=";d.prototype=new Error,d.prototype.name="InvalidCharacterError",b.exports="undefined"!=typeof window&&window.atob&&window.atob.bind(window)||e},{}],2:[function(a,b,c){function d(a){return decodeURIComponent(e(a).replace(/(.)/g,function(a,b){var c=b.charCodeAt(0).toString(16).toUpperCase();return c.length<2&&(c="0"+c),"%"+c}))}var e=a("./atob");b.exports=function(a){var b=a.replace(/-/g,"+").replace(/_/g,"/");switch(b.length%4){case 0:break;case 2:b+="==";break;case 3:b+="=";break;default:throw"Illegal base64url string!"}try{return d(b)}catch(c){return e(b)}}},{"./atob":1}],3:[function(a,b,c){"use strict";function d(a){this.message=a}var e=a("./base64_url_decode");d.prototype=new Error,d.prototype.name="InvalidTokenError",b.exports=function(a,b){if("string"!=typeof a)throw new d("Invalid token specified");b=b||{};var c=b.header===!0?0:1;try{return JSON.parse(e(a.split(".")[c]))}catch(f){throw new d("Invalid token specified: "+f.message)}},b.exports.InvalidTokenError=d},{"./base64_url_decode":2}],4:[function(a,b,c){(function(b){var c=a("./lib/index");"function"==typeof b.window.define&&b.window.define.amd?b.window.define("jwt_decode",function(){return c}):b.window&&(b.window.jwt_decode=c)}).call(this,"undefined"!=typeof global?global:"undefined"!=typeof self?self:"undefined"!=typeof window?window:{})},{"./lib/index":3}]},{},[4]);
--------------------------------------------------------------------------------
/car_admin/src/main/resources/system.properties:
--------------------------------------------------------------------------------
1 |
2 | ######################### 手机短信吗配置#######################
3 | #短信账号
4 | msg.account=LKSDK0005521
5 | #短信密码
6 | msg.password=zh9527@
7 | #短信接口地址
8 | msg.url=http://mb345.com:999/ws/BatchSend2.aspx
9 | msg.code-UUID-mark=MsgCode-UUID-Mark
10 | ######################### 手机短信吗配置#######################
11 |
--------------------------------------------------------------------------------
/car_core/pom.xml:
--------------------------------------------------------------------------------
1 |
3 |
4 | spring-boot-security-with-jwt
5 | com.chinawiserv
6 | 0.0.1-SNAPSHOT
7 |
8 | 4.0.0
9 |
10 | car_core
11 | jar
12 |
13 | car_core
14 | http://maven.apache.org
15 |
16 |
17 | UTF-8
18 |
19 |
20 |
21 |
22 | com.chinawiserv
23 | car_utils
24 | ${project.version}
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 | org.mybatis.spring.boot
34 | mybatis-spring-boot-starter
35 | 1.2.0
36 |
37 |
38 | org.springframework.boot
39 | spring-boot-starter-jdbc
40 |
41 |
42 |
43 |
44 |
45 | tk.mybatis
46 | mapper-spring-boot-starter
47 | 1.1.0
48 |
49 |
50 |
51 | com.github.pagehelper
52 | pagehelper-spring-boot-starter
53 | 1.1.0
54 |
55 |
56 | org.mybatis.spring.boot
57 | mybatis-spring-boot-starter
58 |
59 |
60 |
61 |
62 |
63 |
64 |
--------------------------------------------------------------------------------
/car_core/src/main/java/com/chinawiserv/core/annotation/Auth.java:
--------------------------------------------------------------------------------
1 | package com.chinawiserv.core.annotation;
2 |
3 | import java.lang.annotation.ElementType;
4 | import java.lang.annotation.Retention;
5 | import java.lang.annotation.RetentionPolicy;
6 | import java.lang.annotation.Target;
7 |
8 | /**
9 | * Created by sungang on 2016/8/31.
10 | */
11 |
12 | @Target(ElementType.METHOD)
13 | @Retention(RetentionPolicy.RUNTIME)
14 | public @interface Auth {
15 |
16 | boolean verifyLogin() default false; //验证登录
17 |
18 | boolean verifyWxAuth() default false; //验证企业认证
19 |
20 | boolean verifyAppLogin() default false; //验证用户金额
21 | }
22 |
--------------------------------------------------------------------------------
/car_core/src/main/java/com/chinawiserv/core/constants/Constants.java:
--------------------------------------------------------------------------------
1 | package com.chinawiserv.core.constants;
2 |
3 | /**
4 | * Created with IntelliJ IDEA.
5 | * Date: 2016/6/14
6 | * Time: 14:23
7 | * To change this template use File | Settings | File Templates.
8 | */
9 | public interface Constants {
10 |
11 | /**
12 | * 操作名称
13 | */
14 | String OP_NAME = "op";
15 |
16 |
17 | /**
18 | * 消息key
19 | */
20 | String MESSAGE = "message";
21 |
22 | /**
23 | * 错误key
24 | */
25 | String ERROR = "error";
26 |
27 | /**
28 | * 上个页面地址
29 | */
30 | String BACK_URL = "BackURL";
31 |
32 | String IGNORE_BACK_URL = "ignoreBackURL";
33 |
34 | /**
35 | * 当前请求的地址 带参数
36 | */
37 | String CURRENT_URL = "currentURL";
38 |
39 | /**
40 | * 当前请求的地址 不带参数
41 | */
42 | String NO_QUERYSTRING_CURRENT_URL = "noQueryStringCurrentURL";
43 |
44 |
45 | String CONTEXT_PATH = "ctx";
46 |
47 | /**
48 | * 当前登录的用户
49 | */
50 | String CURRENT_USER = "user";
51 |
52 | /**
53 | * 当前登录的CRM用户
54 | */
55 | String MEMBER_USER = "memberUser";
56 |
57 | /**
58 | * 当前门店id
59 | */
60 | String CURRENT_SHOP_ID = "shop_id";
61 |
62 | /**
63 | * 机器地址
64 | */
65 | String MAC_IP = "127.0.0.1";
66 |
67 | /**
68 | * 扣费金额
69 | */
70 | int CUT_MONEY = 2;
71 | /**
72 | * 当前登录用户名
73 | */
74 | String CURRENT_USERNAME = "username";
75 | /**
76 | * 系统编码
77 | */
78 | String ENCODING = "UTF-8";
79 |
80 |
81 | String AUTH_TOKEN = "auth_token";
82 |
83 | /**
84 | * 状态码
85 | */
86 | //删除状态
87 | final int DELETE = 0;
88 | //未被删除状态,默认状态
89 | final int NORMAL = 1;
90 |
91 | //所有订单查询是查询各个状态的个数
92 | final String EVERY_STATUS_COUNT = "all";
93 |
94 | /**
95 | * 模拟ajax请求成功返回码
96 | */
97 | final String REQUEST_SUCCESS = "200";
98 |
99 | final String SET_TIME_TYPE_PICKUP = "pickUp";
100 | final String SET_TIME_TYPE_DELIVER = "deliver";
101 |
102 | /**
103 | * 积分
104 | */
105 | //基础积分
106 | final int INTEGRAL_BASE = 1;
107 | //赠送积分
108 | final int INTEGRAL_GIVE = 2;
109 |
110 |
111 | final String INTEGRAL_TYPE_ADD = "add";
112 |
113 |
114 | }
115 |
--------------------------------------------------------------------------------
/car_core/src/main/java/com/chinawiserv/core/dao/mybatis/BaseMapper.java:
--------------------------------------------------------------------------------
1 | package com.chinawiserv.core.dao.mybatis;
2 |
3 | import tk.mybatis.mapper.common.ConditionMapper;
4 | import tk.mybatis.mapper.common.IdsMapper;
5 | import tk.mybatis.mapper.common.Mapper;
6 | import tk.mybatis.mapper.common.MySqlMapper;
7 |
8 | import java.io.Serializable;
9 |
10 | /**
11 | * 继承自己的 BaseMapper
12 | */
13 | public interface BaseMapper extends Mapper,MySqlMapper,ConditionMapper, IdsMapper {
14 |
15 | }
16 |
--------------------------------------------------------------------------------
/car_core/src/main/java/com/chinawiserv/core/dao/mybatis/SqlProvider.java:
--------------------------------------------------------------------------------
1 | package com.chinawiserv.core.dao.mybatis;
2 |
3 | /**
4 | * Created by sungang on 2017/3/29.
5 | */
6 | public class SqlProvider {
7 | }
8 |
--------------------------------------------------------------------------------
/car_core/src/main/java/com/chinawiserv/core/dao/mybatis/interceptor/CameHumpInterceptor.java:
--------------------------------------------------------------------------------
1 | package com.chinawiserv.core.dao.mybatis.interceptor;
2 |
3 | import org.apache.ibatis.executor.resultset.ResultSetHandler;
4 | import org.apache.ibatis.plugin.*;
5 |
6 | import java.sql.Statement;
7 | import java.util.*;
8 | import java.util.regex.Matcher;
9 | import java.util.regex.Pattern;
10 |
11 | /**
12 | * MyBatis Map类型大写下划线Key转小写驼峰形式
13 | * 改为拦截ResultSetHandler,更简单的,而且可以避免一级缓存导致重复转换出错
14 | * Created by sungang on 2016/7/4.
15 | */
16 | @Intercepts(
17 | @Signature(type = ResultSetHandler.class, method = "handleResultSets", args = {Statement.class})
18 | )
19 | public class CameHumpInterceptor implements Interceptor {
20 |
21 | @Override
22 | public Object intercept(Invocation invocation) throws Throwable {
23 | //先执行,后处理
24 | List