| | |
| | | <artifactId>mybatis-spring-boot-starter</artifactId> |
| | | <version>2.1.4</version> |
| | | </dependency> |
| | | <dependency> |
| | | <groupId>org.springframework.boot</groupId> |
| | | <artifactId>spring-boot-starter-security</artifactId> |
| | | </dependency> |
| | | |
| | | <!-- druid数据库连接池 --> |
| | | <dependency> |
New file |
| | |
| | | package com.genersoft.iot.vmp.conf.security; |
| | | |
| | | import com.alibaba.fastjson.JSONObject; |
| | | import org.slf4j.Logger; |
| | | import org.slf4j.LoggerFactory; |
| | | import org.springframework.security.core.AuthenticationException; |
| | | import org.springframework.security.web.AuthenticationEntryPoint; |
| | | import org.springframework.stereotype.Component; |
| | | |
| | | import javax.servlet.ServletException; |
| | | import javax.servlet.http.HttpServletRequest; |
| | | import javax.servlet.http.HttpServletResponse; |
| | | import java.io.IOException; |
| | | |
| | | /** |
| | | * 处理匿名用户访问逻辑 |
| | | */ |
| | | @Component |
| | | public class AnonymousAuthenticationEntryPoint implements AuthenticationEntryPoint { |
| | | |
| | | private final static Logger logger = LoggerFactory.getLogger(DefaultUserDetailsServiceImpl.class); |
| | | |
| | | @Override |
| | | public void commence(HttpServletRequest request, HttpServletResponse response, AuthenticationException e) { |
| | | logger.debug("用户需要登录,访问[{}]失败,AuthenticationException=[{}]", request.getRequestURI(), e.getMessage()); |
| | | // 允许跨域 |
| | | response.setHeader("Access-Control-Allow-Origin", "*"); |
| | | // 允许自定义请求头token(允许head跨域) |
| | | response.setHeader("Access-Control-Allow-Headers", "token, Accept, Origin, X-Requested-With, Content-Type, Last-Modified"); |
| | | response.setHeader("Content-type", "application/json;charset=UTF-8"); |
| | | JSONObject jsonObject = new JSONObject(); |
| | | jsonObject.put("msg", e.getMessage()); |
| | | jsonObject.put("code", "-1"); |
| | | response.setStatus(HttpServletResponse.SC_UNAUTHORIZED); |
| | | try { |
| | | response.getWriter().print(jsonObject.toJSONString()); |
| | | } catch (IOException ioException) { |
| | | ioException.printStackTrace(); |
| | | } |
| | | } |
| | | } |
New file |
| | |
| | | package com.genersoft.iot.vmp.conf.security; |
| | | |
| | | import com.genersoft.iot.vmp.conf.security.dto.LoginUser; |
| | | import com.genersoft.iot.vmp.service.IUserService; |
| | | import com.genersoft.iot.vmp.storager.dao.dto.User; |
| | | import com.github.xiaoymin.knife4j.core.util.StrUtil; |
| | | import org.slf4j.Logger; |
| | | import org.slf4j.LoggerFactory; |
| | | import org.springframework.beans.factory.annotation.Autowired; |
| | | import org.springframework.security.core.CredentialsContainer; |
| | | import org.springframework.security.core.GrantedAuthority; |
| | | import org.springframework.security.core.SpringSecurityCoreVersion; |
| | | 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.Component; |
| | | import org.springframework.stereotype.Service; |
| | | |
| | | import java.time.LocalDateTime; |
| | | import java.util.Collection; |
| | | |
| | | /** |
| | | * 用户登录认证逻辑 |
| | | */ |
| | | @Component |
| | | public class DefaultUserDetailsServiceImpl implements UserDetailsService { |
| | | |
| | | private final static Logger logger = LoggerFactory.getLogger(DefaultUserDetailsServiceImpl.class); |
| | | |
| | | @Autowired |
| | | private IUserService userService; |
| | | |
| | | @Override |
| | | public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException { |
| | | if (StrUtil.isBlank(username)) { |
| | | logger.info("登录用户:{} 不存在", username); |
| | | throw new UsernameNotFoundException("登录用户:" + username + " 不存在"); |
| | | } |
| | | |
| | | // 查出密码 |
| | | User user = userService.getUserByUsername(username); |
| | | String password = SecurityUtils.encryptPassword(user.getPassword()); |
| | | user.setPassword(password); |
| | | if (user == null) { |
| | | logger.info("登录用户:{} 不存在", username); |
| | | throw new UsernameNotFoundException("登录用户:" + username + " 不存在"); |
| | | } |
| | | return new LoginUser(user, LocalDateTime.now()); |
| | | } |
| | | |
| | | |
| | | } |
New file |
| | |
| | | package com.genersoft.iot.vmp.conf.security; |
| | | |
| | | import org.slf4j.Logger; |
| | | import org.slf4j.LoggerFactory; |
| | | import org.springframework.security.web.session.InvalidSessionStrategy; |
| | | |
| | | import javax.servlet.ServletException; |
| | | import javax.servlet.http.HttpServletRequest; |
| | | import javax.servlet.http.HttpServletResponse; |
| | | import java.io.IOException; |
| | | |
| | | /** |
| | | * 登录超时的处理 |
| | | */ |
| | | public class InvalidSessionHandler implements InvalidSessionStrategy { |
| | | |
| | | private final static Logger logger = LoggerFactory.getLogger(InvalidSessionHandler.class); |
| | | |
| | | @Override |
| | | public void onInvalidSessionDetected(HttpServletRequest request, HttpServletResponse httpServletResponse) throws IOException, ServletException { |
| | | String username = request.getParameter("username"); |
| | | logger.info("[登录超时] - [{}]", username); |
| | | } |
| | | } |
New file |
| | |
| | | package com.genersoft.iot.vmp.conf.security; |
| | | |
| | | import com.fasterxml.jackson.databind.ObjectMapper; |
| | | import org.slf4j.Logger; |
| | | import org.slf4j.LoggerFactory; |
| | | import org.springframework.beans.factory.annotation.Autowired; |
| | | import org.springframework.security.authentication.*; |
| | | import org.springframework.security.core.AuthenticationException; |
| | | import org.springframework.security.web.authentication.AuthenticationFailureHandler; |
| | | import org.springframework.stereotype.Component; |
| | | |
| | | import javax.servlet.ServletException; |
| | | import javax.servlet.http.HttpServletRequest; |
| | | import javax.servlet.http.HttpServletResponse; |
| | | import java.io.IOException; |
| | | import java.util.HashMap; |
| | | import java.util.Map; |
| | | |
| | | @Component |
| | | public class LoginFailureHandler implements AuthenticationFailureHandler { |
| | | |
| | | private final static Logger logger = LoggerFactory.getLogger(LoginFailureHandler.class); |
| | | |
| | | @Autowired |
| | | private ObjectMapper objectMapper; |
| | | |
| | | @Override |
| | | public void onAuthenticationFailure(HttpServletRequest request, HttpServletResponse response, AuthenticationException e) throws IOException, ServletException { |
| | | |
| | | String username = request.getParameter("username"); |
| | | if (e instanceof AccountExpiredException) { |
| | | // 账号过期 |
| | | logger.info("[登录失败] - 用户[{}]账号过期", username); |
| | | |
| | | } else if (e instanceof BadCredentialsException) { |
| | | // 密码错误 |
| | | logger.info("[登录失败] - 用户[{}]密码错误", username); |
| | | |
| | | } else if (e instanceof CredentialsExpiredException) { |
| | | // 密码过期 |
| | | logger.info("[登录失败] - 用户[{}]密码过期", username); |
| | | |
| | | } else if (e instanceof DisabledException) { |
| | | // 用户被禁用 |
| | | logger.info("[登录失败] - 用户[{}]被禁用", username); |
| | | |
| | | } else if (e instanceof LockedException) { |
| | | // 用户被锁定 |
| | | logger.info("[登录失败] - 用户[{}]被锁定", username); |
| | | |
| | | } else if (e instanceof InternalAuthenticationServiceException) { |
| | | // 内部错误 |
| | | logger.error(String.format("[登录失败] - [%s]内部错误", username), e); |
| | | |
| | | } else { |
| | | // 其他错误 |
| | | logger.error(String.format("[登录失败] - [%s]其他错误", username), e); |
| | | } |
| | | Map<String, Object> map = new HashMap<>(); |
| | | map.put("code","0"); |
| | | map.put("msg","登录失败"); |
| | | response.setContentType("application/json;charset=UTF-8"); |
| | | response.getWriter().write(objectMapper.writeValueAsString(map)); |
| | | } |
| | | } |
New file |
| | |
| | | package com.genersoft.iot.vmp.conf.security; |
| | | |
| | | import org.slf4j.Logger; |
| | | import org.slf4j.LoggerFactory; |
| | | import org.springframework.security.core.Authentication; |
| | | import org.springframework.security.web.authentication.AuthenticationSuccessHandler; |
| | | import org.springframework.stereotype.Component; |
| | | |
| | | import javax.servlet.ServletException; |
| | | import javax.servlet.http.HttpServletRequest; |
| | | import javax.servlet.http.HttpServletResponse; |
| | | import java.io.IOException; |
| | | |
| | | @Component |
| | | public class LoginSuccessHandler implements AuthenticationSuccessHandler { |
| | | |
| | | private final static Logger logger = LoggerFactory.getLogger(LoginSuccessHandler.class); |
| | | |
| | | @Override |
| | | public void onAuthenticationSuccess(HttpServletRequest request, HttpServletResponse httpServletResponse, Authentication authentication) throws IOException, ServletException { |
| | | String username = request.getParameter("username"); |
| | | logger.info("[登录成功] - [{}]", username); |
| | | } |
| | | } |
New file |
| | |
| | | package com.genersoft.iot.vmp.conf.security; |
| | | |
| | | import org.slf4j.Logger; |
| | | import org.slf4j.LoggerFactory; |
| | | import org.springframework.security.core.Authentication; |
| | | import org.springframework.security.web.authentication.logout.LogoutSuccessHandler; |
| | | import org.springframework.stereotype.Component; |
| | | |
| | | import javax.servlet.ServletException; |
| | | import javax.servlet.http.HttpServletRequest; |
| | | import javax.servlet.http.HttpServletResponse; |
| | | import java.io.IOException; |
| | | |
| | | /** |
| | | * 退出登录成功 |
| | | */ |
| | | @Component |
| | | public class LogoutHandler implements LogoutSuccessHandler { |
| | | |
| | | private final static Logger logger = LoggerFactory.getLogger(LogoutHandler.class); |
| | | |
| | | @Override |
| | | public void onLogoutSuccess(HttpServletRequest request, HttpServletResponse httpServletResponse, Authentication authentication) throws IOException, ServletException { |
| | | String username = request.getParameter("username"); |
| | | logger.info("[退出登录成功] - [{}]", username); |
| | | } |
| | | } |
New file |
| | |
| | | package com.genersoft.iot.vmp.conf.security; |
| | | |
| | | import com.genersoft.iot.vmp.conf.security.dto.LoginUser; |
| | | import com.genersoft.iot.vmp.storager.dao.dto.User; |
| | | import gov.nist.javax.sip.address.UserInfo; |
| | | import org.springframework.security.authentication.AuthenticationManager; |
| | | import org.springframework.security.authentication.UsernamePasswordAuthenticationToken; |
| | | import org.springframework.security.core.Authentication; |
| | | import org.springframework.security.core.context.SecurityContext; |
| | | import org.springframework.security.core.context.SecurityContextHolder; |
| | | import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder; |
| | | |
| | | import javax.security.sasl.AuthenticationException; |
| | | |
| | | public class SecurityUtils { |
| | | |
| | | /** |
| | | * 描述根据账号密码进行调用security进行认证授权 主动调 |
| | | * 用AuthenticationManager的authenticate方法实现 |
| | | * 授权成功后将用户信息存入SecurityContext当中 |
| | | * @param username 用户名 |
| | | * @param password 密码 |
| | | * @param authenticationManager 认证授权管理器, |
| | | * @see AuthenticationManager |
| | | * @return UserInfo 用户信息 |
| | | */ |
| | | public static LoginUser login(String username, String password, AuthenticationManager authenticationManager) throws AuthenticationException { |
| | | //使用security框架自带的验证token生成器 也可以自定义。 |
| | | UsernamePasswordAuthenticationToken token =new UsernamePasswordAuthenticationToken(username,password); |
| | | Authentication authenticate = authenticationManager.authenticate(token); |
| | | SecurityContextHolder.getContext().setAuthentication(authenticate); |
| | | LoginUser user = (LoginUser) authenticate.getPrincipal(); |
| | | return user; |
| | | } |
| | | |
| | | /** |
| | | * 获取当前登录的所有认证信息 |
| | | * @return |
| | | */ |
| | | public static Authentication getAuthentication(){ |
| | | SecurityContext context = SecurityContextHolder.getContext(); |
| | | return context.getAuthentication(); |
| | | } |
| | | |
| | | /** |
| | | * 获取当前登录用户信息 |
| | | * @return |
| | | */ |
| | | public static LoginUser getUserInfo(){ |
| | | Authentication authentication = getAuthentication(); |
| | | if(authentication!=null){ |
| | | Object principal = authentication.getPrincipal(); |
| | | if(principal!=null){ |
| | | LoginUser user = (LoginUser) authentication.getPrincipal(); |
| | | return user; |
| | | } |
| | | } |
| | | return null; |
| | | } |
| | | |
| | | /** |
| | | * 获取当前登录用户ID |
| | | * @return |
| | | */ |
| | | public static int getUserId(){ |
| | | LoginUser user = getUserInfo(); |
| | | return user.getId(); |
| | | } |
| | | |
| | | /** |
| | | * 生成BCryptPasswordEncoder密码 |
| | | * |
| | | * @param password 密码 |
| | | * @return 加密字符串 |
| | | */ |
| | | public static String encryptPassword(String password) { |
| | | BCryptPasswordEncoder passwordEncoder = new BCryptPasswordEncoder(); |
| | | return passwordEncoder.encode(password); |
| | | } |
| | | } |
New file |
| | |
| | | package com.genersoft.iot.vmp.conf.security; |
| | | |
| | | import org.springframework.beans.factory.annotation.Autowired; |
| | | import org.springframework.context.annotation.Bean; |
| | | import org.springframework.context.annotation.Configuration; |
| | | import org.springframework.security.authentication.AuthenticationManager; |
| | | import org.springframework.security.authentication.dao.DaoAuthenticationProvider; |
| | | 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.builders.WebSecurity; |
| | | import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity; |
| | | import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter; |
| | | import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder; |
| | | |
| | | /** |
| | | * 配置Spring Security |
| | | */ |
| | | @Configuration |
| | | @EnableWebSecurity |
| | | @EnableGlobalMethodSecurity(prePostEnabled = true) |
| | | public class WebSecurityConfig extends WebSecurityConfigurerAdapter { |
| | | |
| | | @Autowired |
| | | private DefaultUserDetailsServiceImpl userDetailsService; |
| | | /** |
| | | * 登出成功的处理 |
| | | */ |
| | | @Autowired |
| | | private LoginFailureHandler loginFailureHandler; |
| | | /** |
| | | * 登录成功的处理 |
| | | */ |
| | | @Autowired |
| | | private LoginSuccessHandler loginSuccessHandler; |
| | | /** |
| | | * 登出成功的处理 |
| | | */ |
| | | @Autowired |
| | | private LogoutHandler logoutHandler; |
| | | /** |
| | | * 未登录的处理 |
| | | */ |
| | | @Autowired |
| | | private AnonymousAuthenticationEntryPoint anonymousAuthenticationEntryPoint; |
| | | // /** |
| | | // * 超时处理 |
| | | // */ |
| | | // @Autowired |
| | | // private InvalidSessionHandler invalidSessionHandler; |
| | | |
| | | // /** |
| | | // * 顶号处理 |
| | | // */ |
| | | // @Autowired |
| | | // private SessionInformationExpiredHandler sessionInformationExpiredHandler; |
| | | // /** |
| | | // * 登录用户没有权限访问资源 |
| | | // */ |
| | | // @Autowired |
| | | // private LoginUserAccessDeniedHandler accessDeniedHandler; |
| | | |
| | | |
| | | /** |
| | | * 描述: 静态资源放行,这里的放行,是不走 Spring Security 过滤器链 |
| | | **/ |
| | | @Override |
| | | public void configure(WebSecurity web) { |
| | | // 可以直接访问的静态数据 |
| | | web.ignoring() |
| | | .antMatchers("/") |
| | | .antMatchers("/css/**") |
| | | .antMatchers("/img/**") |
| | | .antMatchers("/fonts/**") |
| | | .antMatchers("/index.html") |
| | | .antMatchers("/doc.html") // "/webjars/**", "/swagger-resources/**", "/v3/api-docs/**" |
| | | .antMatchers("/webjars/**") |
| | | .antMatchers("/swagger-resources/**") |
| | | .antMatchers("/v3/api-docs/**") |
| | | .antMatchers("/js/**"); |
| | | } |
| | | |
| | | /** |
| | | * 配置认证方式 |
| | | * @param auth |
| | | * @throws Exception |
| | | */ |
| | | @Override |
| | | protected void configure(AuthenticationManagerBuilder auth) throws Exception { |
| | | DaoAuthenticationProvider provider = new DaoAuthenticationProvider(); |
| | | // 设置不隐藏 未找到用户异常 |
| | | provider.setHideUserNotFoundExceptions(true); |
| | | // 用户认证service - 查询数据库的逻辑 |
| | | provider.setUserDetailsService(userDetailsService); |
| | | // 设置密码加密算法 |
| | | provider.setPasswordEncoder(passwordEncoder()); |
| | | auth.authenticationProvider(provider); |
| | | } |
| | | |
| | | @Override |
| | | protected void configure(HttpSecurity http) throws Exception { |
| | | http.cors().and().csrf().disable(); |
| | | http.authorizeRequests() |
| | | // 放行接口 |
| | | .antMatchers("/api/user/login","/index/hook/**").permitAll() |
| | | // 除上面外的所有请求全部需要鉴权认证 |
| | | .anyRequest().authenticated() |
| | | // 异常处理(权限拒绝、登录失效等) |
| | | .and().exceptionHandling() |
| | | .authenticationEntryPoint(anonymousAuthenticationEntryPoint)//匿名用户访问无权限资源时的异常处理 |
| | | // .accessDeniedHandler(accessDeniedHandler)//登录用户没有权限访问资源 |
| | | // 登入 |
| | | .and().formLogin().permitAll()//允许所有用户 |
| | | .successHandler(loginSuccessHandler)//登录成功处理逻辑 |
| | | .failureHandler(loginFailureHandler)//登录失败处理逻辑 |
| | | // 登出 |
| | | .and().logout().logoutUrl("/api/user/logout").permitAll()//允许所有用户 |
| | | .logoutSuccessHandler(logoutHandler)//登出成功处理逻辑 |
| | | .deleteCookies("JSESSIONID") |
| | | // 会话管理 |
| | | // .and().sessionManagement().invalidSessionStrategy(invalidSessionHandler) // 超时处理 |
| | | // .maximumSessions(1)//同一账号同时登录最大用户数 |
| | | // .expiredSessionStrategy(sessionInformationExpiredHandler) // 顶号处理 |
| | | ; |
| | | |
| | | } |
| | | |
| | | /** |
| | | * 描述: 密码加密算法 BCrypt 推荐使用 |
| | | **/ |
| | | @Bean |
| | | public BCryptPasswordEncoder passwordEncoder() { |
| | | return new BCryptPasswordEncoder(); |
| | | } |
| | | |
| | | /** |
| | | * 描述: 注入AuthenticationManager管理器 |
| | | **/ |
| | | @Override |
| | | @Bean |
| | | public AuthenticationManager authenticationManager() throws Exception { |
| | | return super.authenticationManager(); |
| | | } |
| | | } |
New file |
| | |
| | | package com.genersoft.iot.vmp.conf.security.dto; |
| | | |
| | | import com.genersoft.iot.vmp.storager.dao.dto.User; |
| | | import org.springframework.security.core.CredentialsContainer; |
| | | import org.springframework.security.core.GrantedAuthority; |
| | | import org.springframework.security.core.SpringSecurityCoreVersion; |
| | | import org.springframework.security.core.userdetails.UserDetails; |
| | | |
| | | import java.time.LocalDateTime; |
| | | import java.util.Collection; |
| | | |
| | | public class LoginUser implements UserDetails, CredentialsContainer { |
| | | |
| | | private static final long serialVersionUID = SpringSecurityCoreVersion.SERIAL_VERSION_UID; |
| | | |
| | | /** |
| | | * 用户 |
| | | */ |
| | | private User user; |
| | | |
| | | |
| | | /** |
| | | * 登录时间 |
| | | */ |
| | | private LocalDateTime loginTime; |
| | | |
| | | public LoginUser(User user, LocalDateTime loginTime) { |
| | | this.user = user; |
| | | this.loginTime = loginTime; |
| | | } |
| | | |
| | | |
| | | @Override |
| | | public Collection<? extends GrantedAuthority> getAuthorities() { |
| | | return null; |
| | | } |
| | | |
| | | @Override |
| | | public String getPassword() { |
| | | return user.getPassword(); |
| | | } |
| | | |
| | | @Override |
| | | public String getUsername() { |
| | | return user.getUsername(); |
| | | } |
| | | |
| | | /** |
| | | * 账户是否未过期,过期无法验证 |
| | | */ |
| | | @Override |
| | | public boolean isAccountNonExpired() { |
| | | return true; |
| | | } |
| | | |
| | | /** |
| | | * 指定用户是否解锁,锁定的用户无法进行身份验证 |
| | | * <p> |
| | | * 密码锁定 |
| | | * </p> |
| | | */ |
| | | @Override |
| | | public boolean isAccountNonLocked() { |
| | | return true; |
| | | } |
| | | |
| | | /** |
| | | * 指示是否已过期的用户的凭据(密码),过期的凭据防止认证 |
| | | */ |
| | | @Override |
| | | public boolean isCredentialsNonExpired() { |
| | | return true; |
| | | } |
| | | |
| | | /** |
| | | * 用户是否被启用或禁用。禁用的用户无法进行身份验证。 |
| | | */ |
| | | @Override |
| | | public boolean isEnabled() { |
| | | return true; |
| | | } |
| | | |
| | | /** |
| | | * 认证完成后,擦除密码 |
| | | */ |
| | | @Override |
| | | public void eraseCredentials() { |
| | | user.setPassword(null); |
| | | } |
| | | |
| | | |
| | | public int getId() { |
| | | return user.getId(); |
| | | } |
| | | } |
| | |
| | | |
| | | boolean changePassword(int id, String password); |
| | | |
| | | |
| | | User getUserByUsername(String username); |
| | | } |
| | |
| | | user.setPassword(password); |
| | | return userMapper.update(user) > 0; |
| | | } |
| | | |
| | | @Override |
| | | public User getUserByUsername(String username) { |
| | | return userMapper.getUserByUsername(username); |
| | | } |
| | | } |
| | |
| | | |
| | | @Select("select * FROM user WHERE id= #{id}") |
| | | User selectById(int id); |
| | | |
| | | @Select("select * FROM user WHERE username= #{username}") |
| | | User getUserByUsername(String username); |
| | | } |
| | |
| | | package com.genersoft.iot.vmp.vmanager.user; |
| | | |
| | | import com.genersoft.iot.vmp.conf.security.SecurityUtils; |
| | | import com.genersoft.iot.vmp.conf.security.dto.LoginUser; |
| | | import com.genersoft.iot.vmp.service.IUserService; |
| | | import com.genersoft.iot.vmp.storager.dao.dto.User; |
| | | import io.swagger.annotations.Api; |
| | |
| | | import io.swagger.annotations.ApiOperation; |
| | | import org.springframework.beans.factory.annotation.Autowired; |
| | | import org.springframework.beans.factory.annotation.Value; |
| | | import org.springframework.security.authentication.AuthenticationManager; |
| | | import org.springframework.util.DigestUtils; |
| | | import org.springframework.util.StringUtils; |
| | | import org.springframework.web.bind.annotation.CrossOrigin; |
| | | import org.springframework.web.bind.annotation.GetMapping; |
| | | import org.springframework.web.bind.annotation.RequestMapping; |
| | | import org.springframework.web.bind.annotation.RestController; |
| | | import org.springframework.web.bind.annotation.*; |
| | | |
| | | import javax.security.sasl.AuthenticationException; |
| | | |
| | | @Api(tags = "用户管理") |
| | | @CrossOrigin |
| | |
| | | public class UserController { |
| | | |
| | | @Autowired |
| | | private IUserService userService; |
| | | AuthenticationManager authenticationManager; |
| | | |
| | | @Autowired |
| | | IUserService userService; |
| | | |
| | | @ApiOperation("登录") |
| | | @ApiImplicitParams({ |
| | | @ApiImplicitParam(name = "username", value = "用户名", dataTypeClass = String.class), |
| | | @ApiImplicitParam(name = "password", value = "密码(32未md5加密)", dataTypeClass = String.class), |
| | | @ApiImplicitParam(name = "password", value = "密码(32位md5加密)", dataTypeClass = String.class), |
| | | }) |
| | | @GetMapping("/login") |
| | | public String login(String username, String password){ |
| | | User user = userService.getUser(username, password); |
| | | LoginUser user = null; |
| | | try { |
| | | user = SecurityUtils.login(username, password, authenticationManager); |
| | | } catch (AuthenticationException e) { |
| | | e.printStackTrace(); |
| | | return "fail"; |
| | | } |
| | | if (user != null) { |
| | | return "success"; |
| | | }else { |
| | | return "fail"; |
| | | } |
| | | } |
| | | |
| | | @ApiOperation("修改密码") |
| | | @ApiImplicitParams({ |
| | | @ApiImplicitParam(name = "username", value = "用户名", dataTypeClass = String.class), |
| | | @ApiImplicitParam(name = "password", value = "密码(未md5加密的密码)", dataTypeClass = String.class), |
| | | }) |
| | | @PostMapping("/changePassword") |
| | | public String changePassword(String password){ |
| | | // 获取当前登录用户id |
| | | int userId = SecurityUtils.getUserId(); |
| | | boolean result = userService.changePassword(userId, DigestUtils.md5DigestAsHex(password.getBytes())); |
| | | if (result) { |
| | | return "success"; |
| | | }else { |
| | | return "fail"; |
| | | } |
| | | } |
| | | } |
| | |
| | | pathRewrite: { |
| | | '^/debug': '/' |
| | | } |
| | | } |
| | | }, |
| | | |
| | | }, |
| | | |
| | | // Various Dev Server settings |
| | |
| | | console.log(`修改传输方式为 ${row.streamMode}:${row.deviceId} `); |
| | | let that = this; |
| | | this.$axios({ |
| | | method: 'get', |
| | | url: '/api/device/query/transport' + row.deviceId + '/' + row.streamMode |
| | | method: 'post', |
| | | url: '/api/device/query/transport/' + row.deviceId + '/' + row.streamMode |
| | | }).then(function(res) { |
| | | |
| | | }).catch(function(e) { |
| | |
| | | }); |
| | | } |
| | | }).catch(function (error) { |
| | | that.$message.error(error.response.statusText); |
| | | that.$message.error(error.response.data.msg); |
| | | that.isLoging = false; |
| | | }); |
| | | }, |
| | |
| | | <template> |
| | | <div id="UiHeader"> |
| | | <el-menu router :default-active="this.$route.path" background-color="#545c64" text-color="#fff" active-text-color="#ffd04b" mode="horizontal"> |
| | | <el-menu router :default-active="this.$route.path" menu-trigger="click" background-color="#545c64" text-color="#fff" active-text-color="#ffd04b" mode="horizontal"> |
| | | <el-menu-item index="/">控制台</el-menu-item> |
| | | <el-menu-item index="/deviceList">设备列表</el-menu-item> |
| | | <el-menu-item index="/pushVideoList">推流列表</el-menu-item> |
| | | <el-menu-item index="/streamProxyList">拉流代理</el-menu-item> |
| | | <el-menu-item index="/parentPlatformList/15/1">国标级联</el-menu-item> |
| | | <el-menu-item @click="openDoc">在线文档</el-menu-item> |
| | | <el-switch v-model="alarmNotify" active-text="报警信息推送" style="display: block float: right" @change="sseControl"></el-switch> |
| | | <el-menu-item style="float: right;" @click="loginout">退出</el-menu-item> |
| | | <!-- <el-menu-item style="float: right;" @click="loginout">退出</el-menu-item>--> |
| | | <el-submenu index="" style="float: right;" > |
| | | <template slot="title">欢迎,{{this.$cookies.get("session").username}}</template> |
| | | <el-menu-item @click="changePassword">修改密码</el-menu-item> |
| | | <el-menu-item @click="loginout">注销</el-menu-item> |
| | | </el-submenu> |
| | | </el-menu> |
| | | <changePasswordDialog ref="changePasswordDialog"></changePasswordDialog> |
| | | </div> |
| | | </template> |
| | | |
| | | <script> |
| | | |
| | | import changePasswordDialog from './dialog/changePassword.vue' |
| | | export default { |
| | | name: "UiHeader", |
| | | components: { Notification }, |
| | | components: { Notification, changePasswordDialog }, |
| | | data() { |
| | | return { |
| | | alarmNotify: true, |
| | |
| | | }, |
| | | methods:{ |
| | | loginout(){ |
| | | this.$axios({ |
| | | method: 'get', |
| | | url:"/api/user/logout" |
| | | }).then((res)=> { |
| | | // 删除cookie,回到登录页面 |
| | | this.$cookies.remove("session"); |
| | | this.$router.push('/login'); |
| | | this.sseSource.close(); |
| | | }).catch((error)=> { |
| | | console.error("登出失败") |
| | | console.error(error) |
| | | }); |
| | | }, |
| | | changePassword(){ |
| | | this.$refs.changePasswordDialog.openDialog() |
| | | }, |
| | | openDoc(){ |
| | | console.log(process.env.BASE_API) |
| | | window.open( !!process.env.BASE_API? process.env.BASE_API + "/doc.html": "/doc.html") |
| | | }, |
| | | beforeunloadHandler() { |
| | | this.sseSource.close(); |
New file |
| | |
| | | <template> |
| | | <div id="changePassword" v-loading="isLoging"> |
| | | <el-dialog |
| | | title="修改密码" |
| | | width="40%" |
| | | top="2rem" |
| | | :close-on-click-modal="false" |
| | | :visible.sync="showDialog" |
| | | :destroy-on-close="true" |
| | | @close="close()" |
| | | > |
| | | <div id="shared" style="margin-right: 20px;"> |
| | | <el-form ref="passwordForm" :rules="rules" status-icon label-width="80px"> |
| | | <el-form-item label="新密码" prop="newPassword" > |
| | | <el-input v-model="newPassword" autocomplete="off"></el-input> |
| | | </el-form-item> |
| | | <el-form-item label="确认密码" prop="confirmPassword"> |
| | | <el-input v-model="confirmPassword" autocomplete="off"></el-input> |
| | | </el-form-item> |
| | | |
| | | <el-form-item> |
| | | <div style="float: right;"> |
| | | <el-button type="primary" @click="onSubmit">保存</el-button> |
| | | <el-button @click="close">取消</el-button> |
| | | </div> |
| | | </el-form-item> |
| | | </el-form> |
| | | </div> |
| | | </el-dialog> |
| | | </div> |
| | | </template> |
| | | |
| | | <script> |
| | | export default { |
| | | name: "changePassword", |
| | | props: {}, |
| | | computed: {}, |
| | | created() {}, |
| | | data() { |
| | | let validatePass = (rule, value, callback) => { |
| | | if (value === '') { |
| | | callback(new Error('请输入密码')); |
| | | } else { |
| | | if (this.confirmPassword !== '') { |
| | | this.$refs.passwordForm.validateField('confirmPassword'); |
| | | } |
| | | callback(); |
| | | } |
| | | }; |
| | | let validatePass2 = (rule, value, callback) => { |
| | | if (this.confirmPassword === '') { |
| | | callback(new Error('请再次输入密码')); |
| | | } else if (this.confirmPassword !== this.newPassword) { |
| | | callback(new Error('两次输入密码不一致!')); |
| | | } else { |
| | | callback(); |
| | | } |
| | | }; |
| | | return { |
| | | newPassword: null, |
| | | confirmPassword: null, |
| | | showDialog: false, |
| | | isLoging: false, |
| | | rules: { |
| | | newPassword: [{ required: true, validator: validatePass, trigger: "blur" }], |
| | | confirmPassword: [{ required: true, validator: validatePass2, trigger: "blur" }], |
| | | }, |
| | | }; |
| | | }, |
| | | methods: { |
| | | openDialog: function () { |
| | | this.showDialog = true; |
| | | }, |
| | | onSubmit: function () { |
| | | this.$axios({ |
| | | method: 'post', |
| | | url:"/api/user/changePassword", |
| | | params: { |
| | | password: this.newPassword |
| | | } |
| | | }).then((res)=> { |
| | | if (res.data === "success"){ |
| | | this.$message({ |
| | | showClose: true, |
| | | message: '修改成功,请重新登陆', |
| | | type: 'success' |
| | | }); |
| | | this.showDialog = false; |
| | | setTimeout(()=>{ |
| | | // 删除cookie,回到登录页面 |
| | | this.$cookies.remove("session"); |
| | | this.$router.push('/login'); |
| | | this.sseSource.close(); |
| | | },800) |
| | | } |
| | | }).catch((error)=> { |
| | | console.error(error) |
| | | }); |
| | | }, |
| | | close: function () { |
| | | this.showDialog = false; |
| | | this.newPassword= null; |
| | | this.confirmPassword=null; |
| | | }, |
| | | }, |
| | | }; |
| | | </script> |
| | |
| | | |
| | | axios.defaults.baseURL = (process.env.NODE_ENV === 'development') ? process.env.BASE_API : ""; |
| | | |
| | | // api 返回401自动回登陆页面 |
| | | axios.interceptors.response.use(function (response) { |
| | | // 对响应数据做点什么 |
| | | return response; |
| | | }, function (error) { |
| | | // 对响应错误做点什么 |
| | | if (error.response.status === 401) { |
| | | router.push('/login'); |
| | | } |
| | | return Promise.reject(error); |
| | | }); |
| | | |
| | | Vue.prototype.$cookies.config(60*30); |
| | | |
| | | |