pom.xml
@@ -53,6 +53,23 @@ <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-security</artifactId> </dependency> <dependency> <groupId>org.mybatis.spring.boot</groupId> <artifactId>mybatis-spring-boot-starter</artifactId> <version>1.3.1</version> </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-tomcat</artifactId> </dependency> @@ -61,6 +78,23 @@ <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> </dependency> <dependency> <groupId>org.springframework.security.oauth</groupId> <artifactId>spring-security-oauth2</artifactId> </dependency> <dependency> <groupId>com.alibaba</groupId> <artifactId>druid</artifactId> <version>1.1.5</version> </dependency> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <version>5.1.44</version> </dependency> </dependencies> <build> src/main/java/com/moral/controller/TestController.java
New file @@ -0,0 +1,52 @@ package com.moral.controller; import com.moral.entity.auth.AuthRole; import org.springframework.security.access.prepost.PreAuthorize; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMethod; import org.springframework.web.bind.annotation.ResponseBody; import org.springframework.web.bind.annotation.RestController; import java.util.ArrayList; import java.util.List; @RestController @RequestMapping("/test") public class TestController { @RequestMapping("/hello") public String hello() { return "Hello World"; } @RequestMapping(value = "/list_roles", method = RequestMethod.GET) @PreAuthorize("hasAnyRole('USER', 'ADMIN')") public List<AuthRole> listRoles() { List<AuthRole> roles = new ArrayList<>(); AuthRole role1 = new AuthRole(); role1.setId(1); role1.setRole_name("USER"); roles.add(role1); AuthRole role2 = new AuthRole(); role2.setId(2); role2.setRole_name("USER"); roles.add(role2); return roles; } @RequestMapping(value = "/list_users", method = RequestMethod.GET) @PreAuthorize("hasRole('ADMIN')") public List<String> listUsers() { List<String> data = new ArrayList<>(); data.add("bob"); data.add("bill"); data.add("john"); return data; } } src/main/java/com/moral/controller/TokenController.java
New file @@ -0,0 +1,55 @@ package com.moral.controller; import com.moral.entity.auth.AuthToken; import org.apache.commons.codec.binary.Base64; import org.springframework.http.*; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMethod; import org.springframework.web.bind.annotation.ResponseBody; import org.springframework.web.client.RestTemplate; import java.util.Arrays; import java.util.LinkedHashMap; @Controller public class TokenController { private static final String AUTH_SERVER_URI = "http://localhost:8001/oauth/token?grant_type=password&"; @ResponseBody @RequestMapping(value = "/oauth/token/{username}/{password}", method = RequestMethod.GET) public AuthToken get_auth_token(@PathVariable("username") String username, @PathVariable("password") String password) { RestTemplate restTemplate = new RestTemplate(); HttpEntity<String> request = new HttpEntity<String>(getHeadersWithClientCredentials()); ResponseEntity<Object> response = restTemplate.exchange(AUTH_SERVER_URI+"username="+username+"&password="+password, HttpMethod.POST, request, Object.class); LinkedHashMap<String, Object> map = (LinkedHashMap<String, Object>)response.getBody(); AuthToken token = null; if(map!=null){ token = new AuthToken(); token.setAccess_token((String)map.get("access_token")); token.setToken_type((String)map.get("token_type")); token.setRefresh_token((String)map.get("refresh_token")); token.setExpires_in((Integer)map.get("expires_in")); token.setScope((String)map.get("scope")); System.out.println(token); } return token; } private static HttpHeaders getHeaders(){ HttpHeaders headers = new HttpHeaders(); headers.setAccept(Arrays.asList(MediaType.APPLICATION_JSON)); return headers; } private static HttpHeaders getHeadersWithClientCredentials(){ String plainClientCredentials="my-trusted-client:secret"; String base64ClientCredentials = new String(Base64.encodeBase64(plainClientCredentials.getBytes())); HttpHeaders headers = getHeaders(); headers.add("Authorization", "Basic " + base64ClientCredentials); return headers; } } src/main/java/com/moral/entity/Equipment.java
New file @@ -0,0 +1,156 @@ package com.moral.entity; import java.util.Date; public class Equipment { private Integer id; private String name; private String address; private Double longitude; private Double latitude; private String mac; private Integer state; private Date time; private String installer; private String repairman; private String province; private String city; private String area; private String monitorpoint; private String ownerId; public Integer getId() { return id; } public void setId(Integer id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } public String getAddress() { return address; } public void setAddress(String address) { this.address = address; } public Double getLongitude() { return longitude; } public void setLongitude(Double longitude) { this.longitude = longitude; } public Double getLatitude() { return latitude; } public void setLatitude(Double latitude) { this.latitude = latitude; } public String getMac() { return mac; } public void setMac(String mac) { this.mac = mac; } public Integer getState() { return state; } public void setState(Integer state) { this.state = state; } public Date getTime() { return time; } public void setTime(Date time) { this.time = time; } public String getInstaller() { return installer; } public void setInstaller(String installer) { this.installer = installer; } public String getRepairman() { return repairman; } public void setRepairman(String repairman) { this.repairman = repairman; } public String getProvince() { return province; } public void setProvince(String province) { this.province = province; } public String getCity() { return city; } public void setCity(String city) { this.city = city; } public String getArea() { return area; } public void setArea(String area) { this.area = area; } public String getMonitorpoint() { return monitorpoint; } public void setMonitorpoint(String monitorpoint) { this.monitorpoint = monitorpoint; } public String getOwnerId() { return ownerId; } public void setOwnerId(String ownerId) { this.ownerId = ownerId; } } src/main/java/com/moral/entity/auth/AuthRole.java
New file @@ -0,0 +1,25 @@ package com.moral.entity.auth; import java.io.Serializable; public class AuthRole implements Serializable { private int id; private String role_name; public int getId() { return id; } public void setId(int id) { this.id = id; } public String getRole_name() { return role_name; } public void setRole_name(String role_name) { this.role_name = role_name; } } src/main/java/com/moral/entity/auth/AuthToken.java
New file @@ -0,0 +1,46 @@ package com.moral.entity.auth; public class AuthToken { private String access_token; private String token_type; private String refresh_token; private int expires_in; private String scope; public String getAccess_token() { return access_token; } public void setAccess_token(String access_token) { this.access_token = access_token; } public String getToken_type() { return token_type; } public void setToken_type(String token_type) { this.token_type = token_type; } public String getRefresh_token() { return refresh_token; } public void setRefresh_token(String refresh_token) { this.refresh_token = refresh_token; } public int getExpires_in() { return expires_in; } public void setExpires_in(int expires_in) { this.expires_in = expires_in; } public String getScope() { return scope; } public void setScope(String scope) { this.scope = scope; } @Override public String toString() { return "AuthToken [access_token=" + access_token + ", token_type=" + token_type + ", refresh_token=" + refresh_token + ", expires_in=" + expires_in + ", scope=" + scope + "]"; } } src/main/java/com/moral/entity/auth/AuthUser.java
New file @@ -0,0 +1,44 @@ package com.moral.entity.auth; import java.util.ArrayList; import java.util.List; public class AuthUser { private int id; private String username; private String password; private List<AuthRole> list = new ArrayList<AuthRole>(); public int getId() { return id; } public void setId(int id) { this.id = id; } public String getUsername() { return username; } public void setUsername(String username) { this.username = username; } public String getPassword() { return password; } public void setPassword(String password) { this.password = password; } public List<AuthRole> getList() { return list; } public void setList(List<AuthRole> list) { this.list = list; } } src/main/java/com/moral/mapper/UserMapper.java
New file @@ -0,0 +1,12 @@ package com.moral.mapper; import com.moral.entity.auth.AuthUser; import org.apache.ibatis.annotations.Mapper; import org.springframework.stereotype.Repository; @Mapper @Repository public interface UserMapper { public AuthUser findByUsername(String name); } src/main/java/com/moral/security/AuthorizationServerConfiguration.java
New file @@ -0,0 +1,53 @@ package com.moral.security; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.context.annotation.Configuration; import org.springframework.security.authentication.AuthenticationManager; import org.springframework.security.oauth2.config.annotation.configurers.ClientDetailsServiceConfigurer; import org.springframework.security.oauth2.config.annotation.web.configuration.AuthorizationServerConfigurerAdapter; import org.springframework.security.oauth2.config.annotation.web.configuration.EnableAuthorizationServer; import org.springframework.security.oauth2.config.annotation.web.configurers.AuthorizationServerEndpointsConfigurer; import org.springframework.security.oauth2.config.annotation.web.configurers.AuthorizationServerSecurityConfigurer; import org.springframework.security.oauth2.provider.approval.UserApprovalHandler; import org.springframework.security.oauth2.provider.token.TokenStore; @Configuration @EnableAuthorizationServer public class AuthorizationServerConfiguration extends AuthorizationServerConfigurerAdapter { private static String REALM = "MY_OAUTH_REALM"; @Autowired private TokenStore tokenStore; @Autowired private UserApprovalHandler userApprovalHandler; @Autowired @Qualifier("authenticationManagerBean") private AuthenticationManager authenticationManager; @Override public void configure(ClientDetailsServiceConfigurer clients) throws Exception { clients.inMemory() .withClient("my-trusted-client")//客户端ID .authorizedGrantTypes("password", "authorization_code", "refresh_token", "implicit") .authorities("ROLE_CLIENT", "ROLE_TRUSTED_CLIENT") .scopes("read", "write", "trust")//授权用户的操作权限 .secret("secret")//密码 .accessTokenValiditySeconds(1200).//token有效期为1200秒 refreshTokenValiditySeconds(6000);//刷新token有效期为6000秒 } @Override public void configure(AuthorizationServerEndpointsConfigurer endpoints) throws Exception { endpoints.tokenStore(tokenStore).userApprovalHandler(userApprovalHandler).authenticationManager(authenticationManager); } @Override public void configure(AuthorizationServerSecurityConfigurer oauthServer) throws Exception { oauthServer.realm(REALM + "/client"); } } src/main/java/com/moral/security/ResourceServerConfiguration.java
New file @@ -0,0 +1,31 @@ package com.moral.security; import org.springframework.context.annotation.Configuration; import org.springframework.security.config.annotation.web.builders.HttpSecurity; import org.springframework.security.oauth2.config.annotation.web.configuration.EnableResourceServer; import org.springframework.security.oauth2.config.annotation.web.configuration.ResourceServerConfigurerAdapter; import org.springframework.security.oauth2.config.annotation.web.configurers.ResourceServerSecurityConfigurer; import org.springframework.security.oauth2.provider.error.OAuth2AccessDeniedHandler; @Configuration @EnableResourceServer public class ResourceServerConfiguration extends ResourceServerConfigurerAdapter { private static final String RESOURCE_ID = "my_rest_api"; @Override public void configure(ResourceServerSecurityConfigurer resources) { resources.resourceId(RESOURCE_ID).stateless(false); } @Override public void configure(HttpSecurity http) throws Exception { http.anonymous().disable(); http.requestMatchers() .antMatchers("/test/**") .and() .authorizeRequests() .antMatchers("/test/**").permitAll() .and().exceptionHandling().accessDeniedHandler(new OAuth2AccessDeniedHandler()); } } src/main/java/com/moral/security/WebMvcConfiguration.java
New file @@ -0,0 +1,23 @@ package com.moral.security; import org.springframework.context.annotation.Configuration; import org.springframework.web.servlet.config.annotation.CorsRegistry; import org.springframework.web.servlet.config.annotation.EnableWebMvc; import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter; @Configuration @EnableWebMvc public class WebMvcConfiguration extends WebMvcConfigurerAdapter { @Override public void addCorsMappings(CorsRegistry registry) { registry.addMapping("/**").allowedOrigins("*") .allowedMethods("GET", "POST", "PUT", "DELETE", "PATCH", "HEAD", "OPTIONS") .allowCredentials(false).maxAge(3600); // registry.addMapping("/api/**") // .allowedOrigins("http://192.168.1.97") // .allowedMethods("GET", "POST") // .allowCredentials(false).maxAge(3600); } } src/main/java/com/moral/security/WebSecurityConfiguration.java
New file @@ -0,0 +1,87 @@ package com.moral.security; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.autoconfigure.security.SecurityProperties; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.core.annotation.Order; import org.springframework.data.redis.connection.RedisConnectionFactory; import org.springframework.security.authentication.AuthenticationManager; 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; import org.springframework.security.config.annotation.web.builders.HttpSecurity; import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity; import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter; import org.springframework.security.core.userdetails.UserDetailsService; import org.springframework.security.oauth2.provider.ClientDetailsService; import org.springframework.security.oauth2.provider.approval.ApprovalStore; import org.springframework.security.oauth2.provider.approval.TokenApprovalStore; import org.springframework.security.oauth2.provider.approval.TokenStoreUserApprovalHandler; import org.springframework.security.oauth2.provider.request.DefaultOAuth2RequestFactory; import org.springframework.security.oauth2.provider.token.TokenStore; import org.springframework.security.oauth2.provider.token.store.redis.RedisTokenStore; @Configuration @EnableWebSecurity @EnableGlobalMethodSecurity(prePostEnabled = true) @Order(SecurityProperties.ACCESS_OVERRIDE_ORDER) public class WebSecurityConfiguration extends WebSecurityConfigurerAdapter { @Autowired private ClientDetailsService clientDetailsService; @Autowired private RedisConnectionFactory redisConnection; @Autowired private UserDetailsService userDetailsService; @Override protected void configure(AuthenticationManagerBuilder auth) throws Exception { auth.inMemoryAuthentication() .withUser("bill").password("abc123").roles("ADMIN").and() .withUser("bob").password("abc123").roles("USER"); // auth.userDetailsService(userDetailsService).passwordEncoder(new Md5PasswordEncoder()); } @Override protected void configure(HttpSecurity http) throws Exception { http .anonymous().disable() .authorizeRequests() .antMatchers("/oauth/token").permitAll(); } @Override @Bean public AuthenticationManager authenticationManagerBean() throws Exception { return super.authenticationManagerBean(); } @Bean public TokenStore tokenStore() { //return new InMemoryTokenStore(); return new RedisTokenStore(redisConnection); } @Bean @Autowired public TokenStoreUserApprovalHandler userApprovalHandler(TokenStore tokenStore){ TokenStoreUserApprovalHandler handler = new TokenStoreUserApprovalHandler(); handler.setTokenStore(tokenStore); handler.setRequestFactory(new DefaultOAuth2RequestFactory(clientDetailsService)); handler.setClientDetailsService(clientDetailsService); return handler; } @Bean @Autowired public ApprovalStore approvalStore(TokenStore tokenStore) throws Exception { TokenApprovalStore store = new TokenApprovalStore(); store.setTokenStore(tokenStore); return store; } } src/main/java/com/moral/service/UserService.java
New file @@ -0,0 +1,10 @@ package com.moral.service; import com.moral.entity.auth.AuthUser; import java.util.List; public interface UserService { AuthUser findByUsername(String name); } src/main/java/com/moral/service/impl/AuthUserServiceImpl.java
New file @@ -0,0 +1,38 @@ package com.moral.service.impl; import com.moral.entity.auth.AuthRole; import com.moral.entity.auth.AuthUser; import com.moral.service.UserService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.security.core.authority.SimpleGrantedAuthority; import org.springframework.security.core.userdetails.UserDetails; import org.springframework.security.core.userdetails.UserDetailsService; import org.springframework.security.core.userdetails.UsernameNotFoundException; import org.springframework.stereotype.Service; import java.util.Collection; import java.util.HashSet; import java.util.Iterator; @Service public class AuthUserServiceImpl implements UserDetailsService { @Autowired private UserService userService; @Override public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException { AuthUser user = userService.findByUsername(username); if(user == null){ throw new UsernameNotFoundException("用户名:"+ username + "不存在!"); } Collection<SimpleGrantedAuthority> collection = new HashSet<SimpleGrantedAuthority>(); Iterator<AuthRole> iterator = user.getList().iterator(); while (iterator.hasNext()){ collection.add(new SimpleGrantedAuthority(iterator.next().getRole_name())); } return new org.springframework.security.core.userdetails.User(username, user.getPassword(), collection); } } src/main/java/com/moral/service/impl/UserServiceImpl.java
New file @@ -0,0 +1,22 @@ package com.moral.service.impl; import com.moral.entity.auth.AuthRole; import com.moral.entity.auth.AuthUser; import com.moral.mapper.UserMapper; import com.moral.service.UserService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import java.util.List; @Service public class UserServiceImpl implements UserService { @Autowired private UserMapper userMapper; @Override public AuthUser findByUsername(String name) { return userMapper.findByUsername(name); } } src/main/resources/application.properties
src/main/resources/application.yml
New file @@ -0,0 +1,66 @@ server: port: 8001 session-timeout: 30 tomcat.max-threads: 0 tomcat.uri-encoding: UTF-8 spring: datasource: url: jdbc:mysql://101.37.22.173:3306/monitor?characterEncoding=UTF-8&useSSL=false&serverTimezone=UTC username: root password: xOlx8z9L7Pt6y9YI #driver-class-name: com.mysql.cj.jdbc.Driver type: com.alibaba.druid.pool.DruidDataSource # 下面为连接池的补充设置,应用到上面所有数据源中 # 初始化大小,最小,最大 initialSize: 1 minIdle: 3 maxActive: 20 # 配置获取连接等待超时的时间 maxWait: 60000 # 配置间隔多久才进行一次检测,检测需要关闭的空闲连接,单位是毫秒 timeBetweenEvictionRunsMillis: 60000 # 配置一个连接在池中最小生存的时间,单位是毫秒 minEvictableIdleTimeMillis: 30000 validationQuery: select 'x' testWhileIdle: true testOnBorrow: false testOnReturn: false # 打开PSCache,并且指定每个连接上PSCache的大小 poolPreparedStatements: true maxPoolPreparedStatementPerConnectionSize: 20 # 配置监控统计拦截的filters,去掉后监控界面sql无法统计,'wall'用于防火墙 filters: stat,wall,slf4j # 通过connectProperties属性来打开mergeSql功能;慢SQL记录 connectionProperties: druid.stat.mergeSql=true;druid.stat.slowSqlMillis=5000 # 合并多个DruidDataSource的监控数据 useGlobalDataSourceStat: true rabbitmq: host: 116.62.12.115 port: 5672 username: guest password: guest channelCacheSize: 10 redis: host: 101.37.22.173 port: 6379 password: redis_pass database: 0 timeout: 0 pool: max-active: 8 max-wait: -1 max-idle: 8 min-idle: 0 data: mongodb: uri: mongodb://101.37.22.173:27017/monitor mybatis: mapper-locations: classpath*:/mapper/*Mapper.xml type-aliases-package: com.moral.entity src/main/resources/mapper/UserMapper.xml
New file @@ -0,0 +1,10 @@ <?xml version="1.0" encoding="UTF-8" ?> <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd"> <mapper namespace="com.moral.mapper.UserMapper"> <select id="findByUsername" resultType="com.moral.entity.auth.AuthUser"> </select> </mapper>