增加权限验证
This commit is contained in:
@@ -1,8 +1,5 @@
|
||||
package com.zyplayer.doc.manage;
|
||||
|
||||
import java.net.InetAddress;
|
||||
|
||||
import org.mybatis.spring.annotation.MapperScan;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.boot.SpringApplication;
|
||||
@@ -12,11 +9,12 @@ import org.springframework.boot.web.servlet.support.SpringBootServletInitializer
|
||||
import org.springframework.context.ConfigurableApplicationContext;
|
||||
import org.springframework.core.env.Environment;
|
||||
|
||||
import java.net.InetAddress;
|
||||
|
||||
/**
|
||||
* 程序启动器
|
||||
*/
|
||||
@SpringBootApplication
|
||||
@MapperScan("com.zyplayer.doc.manage.repository")
|
||||
public class Application extends SpringBootServletInitializer {
|
||||
|
||||
private static Logger logger = LoggerFactory.getLogger(Application.class);
|
||||
@@ -25,15 +23,15 @@ public class Application extends SpringBootServletInitializer {
|
||||
protected SpringApplicationBuilder configure(SpringApplicationBuilder application) {
|
||||
return application.sources(Application.class);
|
||||
}
|
||||
|
||||
|
||||
public static void main(String[] args) throws Exception {
|
||||
ConfigurableApplicationContext application = SpringApplication.run(Application.class, args);
|
||||
Environment env = application.getEnvironment();
|
||||
logger.info("\n----------------------------------------------------------\n\t" +
|
||||
"\t\t地址列表\n\t"+
|
||||
"文档地址:http://{}:{}/document.html\n"+
|
||||
"----------------------------------------------------------",
|
||||
InetAddress.getLocalHost().getHostAddress(), env.getProperty("server.port")
|
||||
"\t\t地址列表\n\t" +
|
||||
"文档地址:http://{}:{}/document.html\n" +
|
||||
"----------------------------------------------------------",
|
||||
InetAddress.getLocalHost().getHostAddress(), env.getProperty("server.port")
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -56,5 +56,15 @@ public class MgStorageServiceImpl implements MgStorageService {
|
||||
zyplayerStorageService.save(entity);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除一个key
|
||||
*/
|
||||
@Override
|
||||
public void remove(String key) {
|
||||
UpdateWrapper<ZyplayerStorage> queryWrapper = new UpdateWrapper<>();
|
||||
queryWrapper.eq(true, "doc_key", key);
|
||||
zyplayerStorageService.remove(queryWrapper);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -0,0 +1,141 @@
|
||||
package com.zyplayer.doc.manage.framework.config;
|
||||
|
||||
import com.atomikos.icatch.jta.UserTransactionImp;
|
||||
import com.atomikos.icatch.jta.UserTransactionManager;
|
||||
import com.baomidou.mybatisplus.extension.plugins.PaginationInterceptor;
|
||||
import com.baomidou.mybatisplus.extension.plugins.PerformanceInterceptor;
|
||||
import com.baomidou.mybatisplus.extension.spring.MybatisSqlSessionFactoryBean;
|
||||
import com.zyplayer.doc.manage.repository.support.interceptor.SqlLogInterceptor;
|
||||
import org.apache.ibatis.plugin.Interceptor;
|
||||
import org.mybatis.spring.annotation.MapperScan;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.boot.jta.atomikos.AtomikosDataSourceBean;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.core.io.support.PathMatchingResourcePatternResolver;
|
||||
import org.springframework.transaction.PlatformTransactionManager;
|
||||
import org.springframework.transaction.annotation.EnableTransactionManagement;
|
||||
import org.springframework.transaction.jta.JtaTransactionManager;
|
||||
|
||||
import javax.sql.DataSource;
|
||||
import javax.transaction.TransactionManager;
|
||||
import javax.transaction.UserTransaction;
|
||||
import java.util.Properties;
|
||||
|
||||
/**
|
||||
* mybatis plus数据库配置
|
||||
*/
|
||||
@Configuration
|
||||
public class MybatisPlusConfig {
|
||||
|
||||
/**
|
||||
* sql日志
|
||||
**/
|
||||
private static final SqlLogInterceptor SQL_LOG_INTERCEPTOR;
|
||||
|
||||
static {
|
||||
SQL_LOG_INTERCEPTOR = new SqlLogInterceptor();
|
||||
Properties properties = new Properties();
|
||||
SQL_LOG_INTERCEPTOR.setProperties(properties);
|
||||
}
|
||||
|
||||
/**
|
||||
* 分布式事务配置
|
||||
*/
|
||||
@Configuration
|
||||
static class JTATransactionManagerConfig {
|
||||
|
||||
@Bean(name = "userTransaction")
|
||||
public UserTransaction userTransaction() throws Throwable {
|
||||
UserTransactionImp userTransactionImp = new UserTransactionImp();
|
||||
userTransactionImp.setTransactionTimeout(300);
|
||||
return userTransactionImp;
|
||||
}
|
||||
|
||||
@Bean(name = "atomikosTransactionManager")
|
||||
public TransactionManager atomikosTransactionManager() {
|
||||
UserTransactionManager userTransactionManager = new UserTransactionManager();
|
||||
userTransactionManager.setForceShutdown(true);
|
||||
return userTransactionManager;
|
||||
}
|
||||
|
||||
@Bean(name = "transactionManager")
|
||||
public PlatformTransactionManager transactionManager() throws Throwable {
|
||||
UserTransaction userTransaction = userTransaction();
|
||||
TransactionManager atomikosTransactionManager = atomikosTransactionManager();
|
||||
|
||||
JtaTransactionManager jtaTransactionManager = new JtaTransactionManager(userTransaction, atomikosTransactionManager);
|
||||
jtaTransactionManager.setAllowCustomIsolationLevels(true);
|
||||
jtaTransactionManager.setGlobalRollbackOnParticipationFailure(true);
|
||||
jtaTransactionManager.setDefaultTimeout(30);
|
||||
|
||||
return jtaTransactionManager;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 数据库配置
|
||||
*/
|
||||
@Configuration
|
||||
@EnableTransactionManagement
|
||||
@MapperScan(value = "com.zyplayer.doc.manage.repository.manage.mapper", sqlSessionFactoryRef = "manageSqlSessionFactory")
|
||||
static class ManageMybatisDbConfig {
|
||||
|
||||
@Value("${zyplayer.datasource.manage.driverClassName}")
|
||||
private String driverClassName;
|
||||
@Value("${zyplayer.datasource.manage.url}")
|
||||
private String url;
|
||||
@Value("${zyplayer.datasource.manage.username}")
|
||||
private String username;
|
||||
@Value("${zyplayer.datasource.manage.password}")
|
||||
private String password;
|
||||
|
||||
@Bean(name = "manageDatasource")
|
||||
public DataSource manageDatasource() {
|
||||
Properties xaProperties = new Properties();
|
||||
xaProperties.setProperty("driverClassName", driverClassName);
|
||||
xaProperties.setProperty("url", url);
|
||||
xaProperties.setProperty("username", username);
|
||||
xaProperties.setProperty("password", password);
|
||||
xaProperties.setProperty("maxActive", "500");
|
||||
xaProperties.setProperty("testOnBorrow", "true");
|
||||
xaProperties.setProperty("testWhileIdle", "true");
|
||||
xaProperties.setProperty("validationQuery", "select 'x'");
|
||||
|
||||
AtomikosDataSourceBean xaDataSource = new AtomikosDataSourceBean();
|
||||
xaDataSource.setXaProperties(xaProperties);
|
||||
xaDataSource.setXaDataSourceClassName("com.alibaba.druid.pool.xa.DruidXADataSource");
|
||||
xaDataSource.setUniqueResourceName("manageDatasource");
|
||||
xaDataSource.setMaxPoolSize(500);
|
||||
xaDataSource.setMinPoolSize(1);
|
||||
xaDataSource.setMaxLifetime(60);
|
||||
return xaDataSource;
|
||||
}
|
||||
|
||||
@Bean(name = "manageSqlSessionFactory")
|
||||
public MybatisSqlSessionFactoryBean manageSqlSessionFactory() throws Exception {
|
||||
MybatisSqlSessionFactoryBean sqlSessionFactoryBean = new MybatisSqlSessionFactoryBean();
|
||||
sqlSessionFactoryBean.setDataSource(manageDatasource());
|
||||
sqlSessionFactoryBean.setPlugins(new Interceptor[]{SQL_LOG_INTERCEPTOR});
|
||||
|
||||
PathMatchingResourcePatternResolver resolver = new PathMatchingResourcePatternResolver();
|
||||
sqlSessionFactoryBean.setMapperLocations(resolver.getResources("classpath:/mapper/manage/*Mapper.xml"));
|
||||
return sqlSessionFactoryBean;
|
||||
}
|
||||
}
|
||||
|
||||
@Bean
|
||||
public PerformanceInterceptor performanceInterceptor() {
|
||||
PerformanceInterceptor performanceInterceptor = new PerformanceInterceptor();
|
||||
/* <!-- SQL 执行性能分析,开发环境使用,线上不推荐。 maxTime 指的是 sql 最大执行时长 --> */
|
||||
performanceInterceptor.setMaxTime(1000);
|
||||
/* <!--SQL是否格式化 默认false--> */
|
||||
performanceInterceptor.setFormat(true);
|
||||
return performanceInterceptor;
|
||||
}
|
||||
|
||||
@Bean
|
||||
public PaginationInterceptor paginationInterceptor() {
|
||||
return new PaginationInterceptor();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,46 @@
|
||||
package com.zyplayer.doc.manage.framework.config.security;
|
||||
import java.io.IOException;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import javax.servlet.ServletException;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
|
||||
import org.springframework.security.core.Authentication;
|
||||
import org.springframework.security.web.DefaultRedirectStrategy;
|
||||
import org.springframework.security.web.RedirectStrategy;
|
||||
import org.springframework.security.web.authentication.AuthenticationSuccessHandler;
|
||||
import org.springframework.security.web.savedrequest.HttpSessionRequestCache;
|
||||
import org.springframework.security.web.savedrequest.RequestCache;
|
||||
import org.springframework.security.web.savedrequest.SavedRequest;
|
||||
|
||||
/**
|
||||
* 备用
|
||||
* @author Administrator
|
||||
*
|
||||
*/
|
||||
public class MyAuthenticationSuccessHandler implements AuthenticationSuccessHandler {
|
||||
|
||||
private RequestCache requestCache = new HttpSessionRequestCache();
|
||||
private RedirectStrategy redirectStrategy = new DefaultRedirectStrategy();
|
||||
|
||||
@Override
|
||||
public void onAuthenticationSuccess(HttpServletRequest request, HttpServletResponse response, Authentication authentication) throws IOException, ServletException {
|
||||
SavedRequest savedRequest = requestCache.getRequest(request, response);
|
||||
String targetUrl = savedRequest.getRedirectUrl();
|
||||
// boolean isAjax = HttpHelper.isAjaxRequest(request);
|
||||
boolean isAjax = true;
|
||||
if (isAjax) {
|
||||
Map<String, Object> result = new HashMap<String, Object>();
|
||||
result.put("url", targetUrl);
|
||||
response.getWriter().print(result.toString());
|
||||
response.getWriter().flush();
|
||||
} else {
|
||||
redirectStrategy.sendRedirect(request, response, targetUrl);
|
||||
}
|
||||
|
||||
System.out.println("Redirecting to DefaultSavedRequest Url: " + targetUrl);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,79 @@
|
||||
package com.zyplayer.doc.manage.framework.config.security;
|
||||
|
||||
import java.util.Collection;
|
||||
|
||||
import org.springframework.security.core.GrantedAuthority;
|
||||
import org.springframework.security.core.userdetails.UserDetails;
|
||||
|
||||
public class MyUserDetails implements UserDetails {
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
private Integer userId;
|
||||
private String username;
|
||||
private String password;
|
||||
private boolean enabled;
|
||||
private Collection<? extends GrantedAuthority> authorities;
|
||||
|
||||
public MyUserDetails(Integer userId, String username, String password, boolean enabled) {
|
||||
super();
|
||||
this.userId = userId;
|
||||
this.username = username;
|
||||
this.password = password;
|
||||
this.enabled = enabled;
|
||||
}
|
||||
|
||||
public MyUserDetails(Integer userId, String username, String password, boolean enabled,
|
||||
Collection<? extends GrantedAuthority> authorities) {
|
||||
super();
|
||||
this.userId = userId;
|
||||
this.username = username;
|
||||
this.password = password;
|
||||
this.enabled = enabled;
|
||||
this.authorities = authorities;
|
||||
}
|
||||
|
||||
public Integer getUserId() {
|
||||
return this.userId;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Collection<? extends GrantedAuthority> getAuthorities() {
|
||||
return authorities;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getPassword() {
|
||||
return password;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getUsername() {
|
||||
return username;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isAccountNonExpired() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isAccountNonLocked() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isCredentialsNonExpired() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isEnabled() {
|
||||
return enabled;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "MyUserDetails [userId=" + userId + ", username=" + username + ", password=" + password + ", enabled="
|
||||
+ enabled + ", authorities=" + authorities + "]";
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,49 @@
|
||||
package com.zyplayer.doc.manage.framework.config.security;
|
||||
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
import javax.servlet.http.HttpSession;
|
||||
|
||||
import org.apache.commons.lang.StringUtils;
|
||||
import org.springframework.security.authentication.AuthenticationServiceException;
|
||||
import org.springframework.security.core.Authentication;
|
||||
import org.springframework.security.core.AuthenticationException;
|
||||
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;
|
||||
|
||||
public class MyUsernamePasswordAuthenticationFilter extends UsernamePasswordAuthenticationFilter {
|
||||
// 是否开启验证码功能
|
||||
private boolean isOpenValidateCode = true;
|
||||
|
||||
public static final String VALIDATE_CODE = "validateCode";
|
||||
|
||||
public Authentication attemptAuthentication(HttpServletRequest request, HttpServletResponse response) throws AuthenticationException {
|
||||
if (isOpenValidateCode) {
|
||||
checkValidateCode(request);
|
||||
}
|
||||
return super.attemptAuthentication(request, response);
|
||||
}
|
||||
|
||||
protected void checkValidateCode(HttpServletRequest request) {
|
||||
HttpSession session = request.getSession();
|
||||
|
||||
String sessionValidateCode = obtainSessionValidateCode(session);
|
||||
sessionValidateCode = "1234";// 做个假的验证码;
|
||||
// 让上一次的验证码失效
|
||||
session.setAttribute(VALIDATE_CODE, null);
|
||||
String validateCodeParameter = obtainValidateCodeParameter(request);
|
||||
if (StringUtils.isEmpty(validateCodeParameter) || !sessionValidateCode.equalsIgnoreCase(validateCodeParameter)) {
|
||||
throw new AuthenticationServiceException("验证码错误!");
|
||||
}
|
||||
}
|
||||
|
||||
private String obtainValidateCodeParameter(HttpServletRequest request) {
|
||||
Object obj = request.getParameter(VALIDATE_CODE);
|
||||
return null == obj ? "" : obj.toString();
|
||||
}
|
||||
|
||||
protected String obtainSessionValidateCode(HttpSession session) {
|
||||
Object obj = session.getAttribute(VALIDATE_CODE);
|
||||
return null == obj ? "" : obj.toString();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,30 @@
|
||||
package com.zyplayer.doc.manage.framework.config.security;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.security.core.GrantedAuthority;
|
||||
import org.springframework.security.core.authority.SimpleGrantedAuthority;
|
||||
import org.springframework.security.core.userdetails.UserDetails;
|
||||
import org.springframework.security.core.userdetails.UserDetailsService;
|
||||
import org.springframework.security.core.userdetails.UsernameNotFoundException;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.util.DigestUtils;
|
||||
|
||||
@Service
|
||||
public class UserDetailsServiceImpl implements UserDetailsService {
|
||||
private Logger logger = LoggerFactory.getLogger(this.getClass());
|
||||
|
||||
@Override
|
||||
public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
|
||||
if ("1".equals(username)) {
|
||||
List<GrantedAuthority> authorities = new ArrayList<GrantedAuthority>();
|
||||
authorities.add(new SimpleGrantedAuthority("ROLE_1"));
|
||||
String pwd = DigestUtils.md5DigestAsHex("1".getBytes());
|
||||
return new MyUserDetails(1, "1", pwd, true, authorities);
|
||||
}
|
||||
throw new UsernameNotFoundException("用户名 '" + username + "'没有找到!");
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,26 @@
|
||||
package com.zyplayer.doc.manage.framework.config.security;
|
||||
|
||||
import org.springframework.security.core.Authentication;
|
||||
import org.springframework.security.core.context.SecurityContextHolder;
|
||||
|
||||
/**
|
||||
* 用户工具类
|
||||
*/
|
||||
public class UserUtil {
|
||||
|
||||
/**
|
||||
* 获取当前用户
|
||||
* @return
|
||||
*/
|
||||
public static MyUserDetails getCurrentUser() {
|
||||
Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
|
||||
Object principal = null;
|
||||
if (authentication != null) {
|
||||
principal = authentication.getPrincipal();
|
||||
}
|
||||
if (principal != null && principal instanceof MyUserDetails) {
|
||||
return (MyUserDetails) principal;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,113 @@
|
||||
package com.zyplayer.doc.manage.framework.config.security;
|
||||
//package com.zyplayer.doc.manage.framework.config.security;
|
||||
//
|
||||
//import java.io.IOException;
|
||||
//import java.io.PrintWriter;
|
||||
//
|
||||
//import javax.servlet.ServletException;
|
||||
//import javax.servlet.http.HttpServletRequest;
|
||||
//import javax.servlet.http.HttpServletResponse;
|
||||
//
|
||||
//import org.springframework.beans.factory.annotation.Autowired;
|
||||
//import org.springframework.context.annotation.Bean;
|
||||
//import org.springframework.context.annotation.Configuration;
|
||||
//import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
|
||||
//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.core.Authentication;
|
||||
//import org.springframework.security.core.AuthenticationException;
|
||||
//import org.springframework.security.web.authentication.AuthenticationFailureHandler;
|
||||
//import org.springframework.security.web.authentication.AuthenticationSuccessHandler;
|
||||
//import org.springframework.security.web.authentication.SimpleUrlAuthenticationFailureHandler;
|
||||
//import org.springframework.security.web.authentication.SimpleUrlAuthenticationSuccessHandler;
|
||||
//
|
||||
//@Configuration
|
||||
//@EnableWebSecurity // 注解开启Spring Security的功能
|
||||
//public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
|
||||
//
|
||||
// @Override
|
||||
// protected void configure(HttpSecurity http) throws Exception {
|
||||
// http.authorizeRequests()//定义哪些url需要保护,哪些url不需要保护
|
||||
// .antMatchers("/statics/lib/**", "/message/").permitAll()//定义不需要认证就可以访问
|
||||
// .anyRequest()
|
||||
// .authenticated()
|
||||
// .and()
|
||||
// .formLogin()
|
||||
// .loginPage("/statics/manage/login.html")// 定义当需要用户登录时候,转到的登录页面
|
||||
// .successHandler(new AuthenticationSuccessHandler() {
|
||||
// @Override
|
||||
// public void onAuthenticationSuccess(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Authentication authentication) throws IOException, ServletException {
|
||||
// httpServletResponse.setContentType("application/json;charset=utf-8");
|
||||
// PrintWriter out = httpServletResponse.getWriter();
|
||||
// out.write("{\"status\":\"ok\",\"msg\":\"登录成功\"}");
|
||||
// out.flush();
|
||||
// out.close();
|
||||
// }
|
||||
// }).failureHandler(new AuthenticationFailureHandler() {
|
||||
// @Override
|
||||
// public void onAuthenticationFailure(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, AuthenticationException e) throws IOException, ServletException {
|
||||
// httpServletResponse.setContentType("application/json;charset=utf-8");
|
||||
// PrintWriter out = httpServletResponse.getWriter();
|
||||
// out.write("{\"status\":\"error\",\"msg\":\"登录失败\"}");
|
||||
// out.flush();
|
||||
// out.close();
|
||||
// }
|
||||
// })
|
||||
// .permitAll()
|
||||
// .loginProcessingUrl("/user/login")
|
||||
// .usernameParameter("username")
|
||||
// .passwordParameter("password")
|
||||
// .permitAll()
|
||||
// .and()
|
||||
// .logout()
|
||||
// .permitAll()
|
||||
// .and()
|
||||
// .csrf()
|
||||
// .disable();
|
||||
// }
|
||||
//
|
||||
// @Override
|
||||
// protected void configure(AuthenticationManagerBuilder auth) throws Exception {
|
||||
// auth.userDetailsService(userDetailsServiceImpl());//.passwordEncoder(new Md5PasswordEncoder());
|
||||
// }
|
||||
//
|
||||
// @Bean
|
||||
// public UserDetailsServiceImpl userDetailsServiceImpl() {
|
||||
// return new UserDetailsServiceImpl();
|
||||
// }
|
||||
//
|
||||
// @Bean
|
||||
// public MyUsernamePasswordAuthenticationFilter myUsernamePasswordAuthenticationFilter() throws Exception {
|
||||
// MyUsernamePasswordAuthenticationFilter myFilter = new MyUsernamePasswordAuthenticationFilter();
|
||||
// myFilter.setAuthenticationManager(authenticationManagerBean());
|
||||
// myFilter.setAuthenticationSuccessHandler(authenticationSuccessHandler());
|
||||
// myFilter.setAuthenticationFailureHandler(authenticationFailureHandler());
|
||||
// myFilter.setRememberMeServices(tokenBasedRememberMeServices());
|
||||
// return myFilter;
|
||||
// }
|
||||
//
|
||||
// @Bean
|
||||
// public AuthenticationSuccessHandler authenticationSuccessHandler() {
|
||||
// return new SimpleUrlAuthenticationSuccessHandler("/login/success");
|
||||
// }
|
||||
//
|
||||
// @Bean
|
||||
// public AuthenticationFailureHandler authenticationFailureHandler() {
|
||||
// return new SimpleUrlAuthenticationFailureHandler("/login/failure");
|
||||
// }
|
||||
//
|
||||
// @Override
|
||||
// public void configure(WebSecurity web) throws Exception {
|
||||
// web.ignoring().antMatchers("/statics/lib/**", "**/css/**", "**/js/**", "**/img/**");
|
||||
// }
|
||||
//
|
||||
// @Autowired
|
||||
// public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
|
||||
// //在内存中创建了一个用户,该用户的名称为user,密码为password,用户角色为ADMIN
|
||||
// auth.inMemoryAuthentication()
|
||||
// .withUser("user").password("password").roles("ADMIN");
|
||||
// }
|
||||
//}
|
||||
//
|
||||
@@ -0,0 +1,137 @@
|
||||
package com.zyplayer.doc.manage.framework.config.security;
|
||||
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.core.annotation.Order;
|
||||
import org.springframework.security.authentication.AuthenticationManager;
|
||||
import org.springframework.security.authentication.RememberMeAuthenticationProvider;
|
||||
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
|
||||
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.password.PasswordEncoder;
|
||||
import org.springframework.security.web.authentication.AuthenticationFailureHandler;
|
||||
import org.springframework.security.web.authentication.AuthenticationSuccessHandler;
|
||||
import org.springframework.security.web.authentication.LoginUrlAuthenticationEntryPoint;
|
||||
import org.springframework.security.web.authentication.SimpleUrlAuthenticationFailureHandler;
|
||||
import org.springframework.security.web.authentication.SimpleUrlAuthenticationSuccessHandler;
|
||||
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;
|
||||
import org.springframework.security.web.authentication.rememberme.RememberMeAuthenticationFilter;
|
||||
import org.springframework.security.web.authentication.rememberme.TokenBasedRememberMeServices;
|
||||
import org.springframework.util.DigestUtils;
|
||||
|
||||
@Configuration
|
||||
@EnableWebSecurity
|
||||
@Order(1)
|
||||
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
|
||||
|
||||
@Bean
|
||||
@Override
|
||||
public AuthenticationManager authenticationManagerBean() throws Exception {
|
||||
return super.authenticationManagerBean();
|
||||
}
|
||||
|
||||
/**
|
||||
* 忽略静态文件
|
||||
*/
|
||||
@Override
|
||||
public void configure(WebSecurity web) throws Exception {
|
||||
web.ignoring().antMatchers("/statics/lib/**", "/css/**", "/js/**", "/img/**");
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void configure(HttpSecurity http) throws Exception {
|
||||
http.authorizeRequests().antMatchers("/login/**").permitAll()//为了测试其他功能,设置“ /** ”允许所有请求
|
||||
// user权限可以访问的请求
|
||||
.antMatchers("/security/user").hasRole("user")
|
||||
// admin权限可以访问的请求
|
||||
.antMatchers("/security/admin").hasRole("admin")
|
||||
// SpEL表达式:需要拥有user权限,且进行了完全认证
|
||||
.antMatchers("/user/account").access("hasRole('user') and isFullyAuthenticated()")
|
||||
// 其他地址的访问均需验证权限(需要登录)
|
||||
.anyRequest().authenticated().and()
|
||||
// 添加验证码验证
|
||||
.addFilterAt(myUsernamePasswordAuthenticationFilter(), UsernamePasswordAuthenticationFilter.class).exceptionHandling()
|
||||
.authenticationEntryPoint(new LoginUrlAuthenticationEntryPoint("/statics/manage/login.html")).and()
|
||||
.addFilterAt(rememberMeAuthenticationFilter(), RememberMeAuthenticationFilter.class)
|
||||
// 指定登录页面的请求路径
|
||||
.formLogin().loginPage("/statics/manage/login.html")
|
||||
// 登陆处理路径
|
||||
.loginProcessingUrl("/login").permitAll().and()
|
||||
// 退出请求的默认路径为logout,下面改为signout,
|
||||
// 成功退出登录后的url可以用logoutSuccessUrl设置
|
||||
.logout().deleteCookies("remember-me")
|
||||
.logoutUrl("/signout")
|
||||
.logoutSuccessUrl("/statics/manage/login.html")
|
||||
.permitAll().and()
|
||||
// 开启rememberMe,设置一个私钥专供testall项目使用,注意与下面TokenBasedRememberMeServices的key保持一致
|
||||
// .rememberMe().key("testallKey").and()
|
||||
// 关闭csrf
|
||||
.csrf().disable();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
|
||||
auth.userDetailsService(userDetailsServiceImpl())
|
||||
.passwordEncoder(new PasswordEncoder() {
|
||||
@Override
|
||||
public String encode(CharSequence charSequence) {
|
||||
return DigestUtils.md5DigestAsHex(charSequence.toString().getBytes());
|
||||
}
|
||||
@Override
|
||||
public boolean matches(CharSequence charSequence, String s) {
|
||||
return s.equals(DigestUtils.md5DigestAsHex(charSequence.toString().getBytes()));
|
||||
}
|
||||
}).and().authenticationProvider(rememberMeAuthenticationProvider());
|
||||
}
|
||||
|
||||
@Bean
|
||||
public UserDetailsServiceImpl userDetailsServiceImpl() {
|
||||
return new UserDetailsServiceImpl();
|
||||
}
|
||||
|
||||
@Bean
|
||||
public MyUsernamePasswordAuthenticationFilter myUsernamePasswordAuthenticationFilter() throws Exception {
|
||||
MyUsernamePasswordAuthenticationFilter myFilter = new MyUsernamePasswordAuthenticationFilter();
|
||||
myFilter.setAuthenticationManager(authenticationManagerBean());
|
||||
myFilter.setAuthenticationSuccessHandler(authenticationSuccessHandler());
|
||||
myFilter.setAuthenticationFailureHandler(authenticationFailureHandler());
|
||||
myFilter.setRememberMeServices(tokenBasedRememberMeServices());
|
||||
return myFilter;
|
||||
}
|
||||
|
||||
@Bean
|
||||
public AuthenticationSuccessHandler authenticationSuccessHandler() {
|
||||
return new SimpleUrlAuthenticationSuccessHandler("/login/success");
|
||||
}
|
||||
|
||||
@Bean
|
||||
public AuthenticationFailureHandler authenticationFailureHandler() {
|
||||
return new SimpleUrlAuthenticationFailureHandler("/login/failure");
|
||||
}
|
||||
|
||||
@Bean
|
||||
public TokenBasedRememberMeServices tokenBasedRememberMeServices() {
|
||||
TokenBasedRememberMeServices tbrms = new TokenBasedRememberMeServices("testallKey", userDetailsServiceImpl());
|
||||
// 设置cookie过期时间为2天
|
||||
tbrms.setTokenValiditySeconds(60 * 60 * 24 * 2);
|
||||
// 设置checkbox的参数名为rememberMe(默认为remember-me),注意如果是ajax请求,参数名不是checkbox的name而是在ajax的data里
|
||||
tbrms.setParameter("rememberMe");
|
||||
tbrms.setAlwaysRemember(false);
|
||||
return tbrms;
|
||||
}
|
||||
|
||||
@Bean
|
||||
public RememberMeAuthenticationProvider rememberMeAuthenticationProvider() {
|
||||
RememberMeAuthenticationProvider rmap = new RememberMeAuthenticationProvider("testallKey");
|
||||
return rmap;
|
||||
}
|
||||
|
||||
@Bean
|
||||
public RememberMeAuthenticationFilter rememberMeAuthenticationFilter() throws Exception {
|
||||
RememberMeAuthenticationFilter myFilter = new RememberMeAuthenticationFilter(authenticationManagerBean(), tokenBasedRememberMeServices());
|
||||
return myFilter;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,38 @@
|
||||
package com.zyplayer.doc.manage.framework.interceptor;
|
||||
|
||||
import javax.servlet.ServletContext;
|
||||
|
||||
import org.springframework.beans.factory.InitializingBean;
|
||||
import org.springframework.stereotype.Component;
|
||||
import org.springframework.web.context.ServletContextAware;
|
||||
|
||||
/**
|
||||
* 所有bean初始化后执行,bean初始化了,再初始化一些自己的东西
|
||||
*/
|
||||
@Component
|
||||
public class InitServletContextAware implements InitializingBean,ServletContextAware {
|
||||
|
||||
private ServletContext context;
|
||||
|
||||
@Override
|
||||
public void setServletContext(ServletContext context) {
|
||||
this.context = context;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void afterPropertiesSet() throws Exception {
|
||||
ctx();
|
||||
}
|
||||
|
||||
private void ctx(){
|
||||
String ctx = context.getContextPath();
|
||||
if (ctx != null && ctx.trim().length() > 0 && !ctx.trim().equals("/")) {
|
||||
context.setAttribute("ctx", ctx+"/");
|
||||
context.setAttribute("statics", ctx+"/statics/");
|
||||
} else {
|
||||
context.setAttribute("ctx", "/");
|
||||
context.setAttribute("statics", "/statics/");
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,127 @@
|
||||
package com.zyplayer.doc.manage.repository.support.interceptor;
|
||||
|
||||
import java.text.DateFormat;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
import java.util.Properties;
|
||||
|
||||
import org.apache.ibatis.executor.Executor;
|
||||
import org.apache.ibatis.mapping.BoundSql;
|
||||
import org.apache.ibatis.mapping.MappedStatement;
|
||||
import org.apache.ibatis.mapping.ParameterMapping;
|
||||
import org.apache.ibatis.plugin.Interceptor;
|
||||
import org.apache.ibatis.plugin.Intercepts;
|
||||
import org.apache.ibatis.plugin.Invocation;
|
||||
import org.apache.ibatis.plugin.Plugin;
|
||||
import org.apache.ibatis.plugin.Signature;
|
||||
import org.apache.ibatis.reflection.MetaObject;
|
||||
import org.apache.ibatis.session.Configuration;
|
||||
import org.apache.ibatis.session.ResultHandler;
|
||||
import org.apache.ibatis.session.RowBounds;
|
||||
import org.apache.ibatis.type.TypeHandlerRegistry;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
@Intercepts({
|
||||
@Signature(type = Executor.class, method = "update", args = { MappedStatement.class, Object.class }),
|
||||
@Signature(type = Executor.class, method = "query", args = { MappedStatement.class, Object.class, RowBounds.class, ResultHandler.class })
|
||||
})
|
||||
public class SqlLogInterceptor implements Interceptor {
|
||||
|
||||
private static final Logger LOGGER = LoggerFactory.getLogger(SqlLogInterceptor.class);
|
||||
|
||||
@Override
|
||||
public Object intercept(Invocation invocation) throws Throwable {
|
||||
MappedStatement mappedStatement = (MappedStatement) invocation.getArgs()[0];
|
||||
Object parameter = null;
|
||||
if (invocation.getArgs().length > 1) {
|
||||
parameter = invocation.getArgs()[1];
|
||||
}
|
||||
BoundSql boundSql = mappedStatement.getBoundSql(parameter);
|
||||
Configuration configuration = mappedStatement.getConfiguration();
|
||||
// 获取sql语句
|
||||
String sql = getSqlString(configuration, boundSql);
|
||||
LOGGER.info(sql);
|
||||
// 执行结果
|
||||
return invocation.proceed();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object plugin(Object target) {
|
||||
if (target instanceof Executor) {
|
||||
return Plugin.wrap(target, this);
|
||||
} else {
|
||||
return target;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setProperties(Properties properties) {
|
||||
}
|
||||
|
||||
private String getParameterValue(Object obj) {
|
||||
String value = null;
|
||||
if (obj instanceof String) {
|
||||
value = "'" + obj.toString() + "'";
|
||||
} else if (obj instanceof Date) {
|
||||
DateFormat formatter = DateFormat.getDateTimeInstance(DateFormat.DEFAULT, DateFormat.DEFAULT, Locale.CHINA);
|
||||
value = "'" + formatter.format(obj) + "'";
|
||||
//System.out.println(value);
|
||||
} else {
|
||||
if (obj != null) {
|
||||
value = obj.toString();
|
||||
} else {
|
||||
value = "'null'";
|
||||
}
|
||||
}
|
||||
return value;
|
||||
}
|
||||
|
||||
public String getSqlString(Configuration configuration, BoundSql boundSql) {
|
||||
Object parameterObject = boundSql.getParameterObject();
|
||||
List<ParameterMapping> parameterMappings = boundSql.getParameterMappings();
|
||||
StringBuilder sqlSb = new StringBuilder(boundSql.getSql().replaceAll("[\\s]+", " "));
|
||||
int fromIndex = 0;
|
||||
if (parameterMappings.size() > 0 && parameterObject != null) {
|
||||
TypeHandlerRegistry typeHandlerRegistry = configuration.getTypeHandlerRegistry();
|
||||
if (typeHandlerRegistry.hasTypeHandler(parameterObject.getClass())) {
|
||||
//sqlSb = sqlSb.replaceFirst("\\?", getParameterValue(parameterObject));
|
||||
fromIndex = replacePlaceholder(sqlSb, fromIndex, getParameterValue(parameterObject));
|
||||
} else {
|
||||
MetaObject metaObject = configuration.newMetaObject(parameterObject);
|
||||
for (ParameterMapping parameterMapping : parameterMappings) {
|
||||
String propertyName = parameterMapping.getProperty();
|
||||
if (metaObject.hasGetter(propertyName)) {
|
||||
Object obj = metaObject.getValue(propertyName);
|
||||
//sqlSb = sqlSb.replaceFirst("\\?", getParameterValue(obj));
|
||||
fromIndex = replacePlaceholder(sqlSb, fromIndex, getParameterValue(obj));
|
||||
} else if (boundSql.hasAdditionalParameter(propertyName)) {
|
||||
Object obj = boundSql.getAdditionalParameter(propertyName);
|
||||
//sqlSb = sqlSb.replaceFirst("\\?", getParameterValue(obj));
|
||||
fromIndex = replacePlaceholder(sqlSb, fromIndex, getParameterValue(obj));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return sqlSb.toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* 替换?占位符
|
||||
* @author 暮光:城中城
|
||||
* @since 2018年10月27日
|
||||
* @param sql
|
||||
* @param fromIndex
|
||||
* @param replaceStr
|
||||
* @return
|
||||
*/
|
||||
private int replacePlaceholder(StringBuilder sql, int fromIndex, String replaceStr) {
|
||||
int index = sql.indexOf("?", fromIndex);
|
||||
if (index >= 0) {
|
||||
sql.replace(index, index + 1, replaceStr);
|
||||
}
|
||||
return index + replaceStr.length();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,23 @@
|
||||
package com.zyplayer.doc.manage.web.manage;
|
||||
|
||||
import org.springframework.stereotype.Controller;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
|
||||
@Controller
|
||||
public class HelloController {
|
||||
|
||||
// @RequestMapping("/")
|
||||
// public String index() {
|
||||
// return "manage/index";
|
||||
// }
|
||||
//
|
||||
// @RequestMapping("/hello")
|
||||
// public String hello() {
|
||||
// return "manage/hello";
|
||||
// }
|
||||
//
|
||||
// @RequestMapping("/login")
|
||||
// public String login() {
|
||||
// return "statics/manage/hello.html";
|
||||
// }
|
||||
}
|
||||
@@ -0,0 +1,123 @@
|
||||
package com.zyplayer.doc.manage.web.manage;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
|
||||
import org.springframework.security.core.AuthenticationException;
|
||||
import org.springframework.security.core.GrantedAuthority;
|
||||
import org.springframework.security.web.WebAttributes;
|
||||
import org.springframework.security.web.savedrequest.HttpSessionRequestCache;
|
||||
import org.springframework.security.web.savedrequest.RequestCache;
|
||||
import org.springframework.security.web.savedrequest.SavedRequest;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RequestMethod;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
import org.springframework.web.servlet.ModelAndView;
|
||||
|
||||
import com.zyplayer.doc.manage.framework.config.security.MyUserDetails;
|
||||
import com.zyplayer.doc.manage.framework.config.security.UserUtil;
|
||||
|
||||
@RestController
|
||||
public class UserController {
|
||||
private RequestCache requestCache = new HttpSessionRequestCache();
|
||||
|
||||
@RequestMapping(value = "/login_page", method = RequestMethod.GET)
|
||||
public ModelAndView loginPage(HttpServletRequest request) {
|
||||
if (true) {
|
||||
return new ModelAndView("/login/ajax");
|
||||
} else {
|
||||
return new ModelAndView("login.html");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* 如果是访问受限页面后,跳转到登录页的,则在targetUrl保存之前受限页面的路径,供页面调用
|
||||
*
|
||||
* @param request
|
||||
* @param response
|
||||
* @return
|
||||
*/
|
||||
@RequestMapping(value = "/login/success", method = RequestMethod.GET)
|
||||
public Map<String, Object> loginSuccess(HttpServletRequest request, HttpServletResponse response) {
|
||||
SavedRequest savedRequest = requestCache.getRequest(request, response);
|
||||
String targetUrl = null;
|
||||
if (savedRequest != null) {
|
||||
targetUrl = savedRequest.getRedirectUrl();
|
||||
}
|
||||
Map<String, Object> result = new HashMap<String, Object>();
|
||||
result.put("success", true);
|
||||
result.put("targetUrl", targetUrl);
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取异常信息返回给页面
|
||||
* @param request
|
||||
* @param response
|
||||
* @return
|
||||
*/
|
||||
@RequestMapping(value = "/login/failure", method = RequestMethod.GET)
|
||||
public Map<String, Object> loginFailure(HttpServletRequest request, HttpServletResponse response) {
|
||||
AuthenticationException ae = (AuthenticationException) request.getSession().getAttribute(WebAttributes.AUTHENTICATION_EXCEPTION);
|
||||
Map<String, Object> result = new HashMap<String, Object>();
|
||||
result.put("success", false);
|
||||
result.put("message", ae.getMessage());
|
||||
return result;
|
||||
}
|
||||
|
||||
@RequestMapping(value = "/login/ajax", method = RequestMethod.GET)
|
||||
public Map<String, Object> loginAjax() {
|
||||
Map<String, Object> result = new HashMap<String, Object>();
|
||||
result.put("success", false);
|
||||
result.put("message", "you need login!");
|
||||
return result;
|
||||
}
|
||||
|
||||
@RequestMapping(value = "/security/user", method = RequestMethod.GET)
|
||||
public Map<String, Object> securityUser(HttpServletRequest request) {
|
||||
MyUserDetails user = UserUtil.getCurrentUser();
|
||||
Map<String, Object> result = new HashMap<String, Object>();
|
||||
StringBuilder userRole = new StringBuilder();
|
||||
if (user != null) {
|
||||
result.put("userId", user.getUserId());
|
||||
result.put("userName", user.getUsername());
|
||||
Collection<? extends GrantedAuthority> roleLst = user.getAuthorities();
|
||||
for (GrantedAuthority sga : roleLst) {
|
||||
userRole.append(sga.toString() + "; ");
|
||||
}
|
||||
}
|
||||
result.put("userRole", userRole.toString());
|
||||
result.put("message", "This message is only visible to the user");
|
||||
return result;
|
||||
}
|
||||
|
||||
@RequestMapping(value = "/security/admin", method = RequestMethod.GET)
|
||||
public Map<String, Object> securityAdmin(HttpServletRequest request) {
|
||||
MyUserDetails user = UserUtil.getCurrentUser();
|
||||
Map<String, Object> result = new HashMap<String, Object>();
|
||||
StringBuilder userRole = new StringBuilder();
|
||||
if (user != null) {
|
||||
result.put("userId", user.getUserId());
|
||||
result.put("userName", user.getUsername());
|
||||
Collection<? extends GrantedAuthority> roleLst = user.getAuthorities();
|
||||
for (GrantedAuthority sga : roleLst) {
|
||||
userRole.append(sga.toString() + "; ");
|
||||
}
|
||||
}
|
||||
result.put("userRole", userRole.toString());
|
||||
result.put("message", "This message is only visible to the admin");
|
||||
return result;
|
||||
}
|
||||
|
||||
@RequestMapping(value = "/user/account", method = RequestMethod.GET)
|
||||
public Map<String, Object> getUserAcctunt(HttpServletRequest request) {
|
||||
Map<String, Object> result = new HashMap<String, Object>();
|
||||
result.put("message", "需要进行完整认证的请求(不是通过Remember-me功能进行的认证)");
|
||||
return result;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user