Browse Source

物联网登录

LiTaohong 7 years ago
parent
commit
4e80a415ba
27 changed files with 839 additions and 552 deletions
  1. 5 10
      app/app-iot-server/pom.xml
  2. 1 1
      app/app-iot-server/src/main/java/com/yihu/ehr/iot/AppIotServer.java
  3. 0 27
      app/app-iot-server/src/main/java/com/yihu/ehr/iot/config/ErrorPageConfig.java
  4. 0 87
      app/app-iot-server/src/main/java/com/yihu/ehr/iot/config/SpringSecurityConfig.java
  5. 0 47
      app/app-iot-server/src/main/java/com/yihu/ehr/iot/config/WebMvcConfig.java
  6. 4 2
      app/app-iot-server/src/main/java/com/yihu/ehr/iot/controller/common/LoginController.java
  7. 0 28
      app/app-iot-server/src/main/java/com/yihu/ehr/iot/interceptor/LoginInterceptor.java
  8. 0 99
      app/app-iot-server/src/main/java/com/yihu/ehr/iot/security/AccessDecisionManagerImpl.java
  9. 0 60
      app/app-iot-server/src/main/java/com/yihu/ehr/iot/security/AccessDeniedHandlerImpl.java
  10. 0 163
      app/app-iot-server/src/main/java/com/yihu/ehr/iot/security/RoleCache.java
  11. 20 0
      app/app-iot-server/src/main/java/com/yihu/ehr/iot/security/config/EhrWebHttpSessionConfiguration.java
  12. 106 0
      app/app-iot-server/src/main/java/com/yihu/ehr/iot/security/config/EhrWebSecurityConfiguration.java
  13. 95 0
      app/app-iot-server/src/main/java/com/yihu/ehr/iot/security/core/EhrWebAccessDecisionManager.java
  14. 156 0
      app/app-iot-server/src/main/java/com/yihu/ehr/iot/security/core/EhrWebAuthenticationProvider.java
  15. 51 0
      app/app-iot-server/src/main/java/com/yihu/ehr/iot/security/core/EhrWebAuthenticationSuccessHandler.java
  16. 54 0
      app/app-iot-server/src/main/java/com/yihu/ehr/iot/security/core/EhrWebAuthenticationToken.java
  17. 47 0
      app/app-iot-server/src/main/java/com/yihu/ehr/iot/security/core/EhrWebUserDetails.java
  18. 86 0
      app/app-iot-server/src/main/java/com/yihu/ehr/iot/security/core/EhrWebUserDetailsService.java
  19. 178 0
      app/app-iot-server/src/main/java/com/yihu/ehr/iot/security/core/EhrWebUsernamePasswordAuthenticationFilter.java
  20. 18 12
      app/app-iot-server/src/main/resources/application.yml
  21. 2 2
      app/app-iot-server/src/main/webapp/front/js/common/apiServer.js
  22. 1 1
      app/app-iot-server/src/main/webapp/front/js/common/config.js
  23. 1 1
      app/app-iot-server/src/main/webapp/front/js/scripts/login.js
  24. 1 1
      app/app-iot-server/src/main/webapp/front/js/scripts/signin.js
  25. 7 7
      app/app-iot-server/src/main/webapp/front/views/login.html
  26. 3 2
      svr/svr-manage/src/main/java/com/yihu/jw/manage/controller/wechat/GraphicMessageController.java
  27. 3 2
      svr/svr-manage/src/main/java/com/yihu/jw/manage/controller/wechat/WechatMenuController.java

+ 5 - 10
app/app-iot-server/pom.xml

@ -1,23 +1,18 @@
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <groupId>com.yihu.ehr</groupId>
    <groupId>com.yihu.ehr.iot</groupId>
    <artifactId>app-iot-server</artifactId>
    <packaging>war</packaging>
    <version>1.0.0</version>
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>1.4.0.RELEASE</version>
        <relativePath>pom.xml</relativePath>
        <groupId>com.yihu.jw</groupId>
        <artifactId>svr-lib-parent-pom</artifactId>
        <version>1.0.0</version>
        <relativePath>../../svr-lib-parent-pom/pom.xml</relativePath>
    </parent>
    <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <java.version>1.8</java.version>
    </properties>
    <!-- 依赖包 -->
    <dependencies>
        <dependency>

+ 1 - 1
app/app-iot-server/src/main/java/com/yihu/ehr/iot/AppIotServer.java

@ -9,7 +9,7 @@ import org.springframework.boot.autoconfigure.jdbc.DataSourceTransactionManagerA
import org.springframework.boot.autoconfigure.orm.jpa.HibernateJpaAutoConfiguration;
import org.springframework.boot.autoconfigure.security.SecurityAutoConfiguration;
import org.springframework.boot.builder.SpringApplicationBuilder;
import org.springframework.boot.context.web.SpringBootServletInitializer;
import org.springframework.boot.web.support.SpringBootServletInitializer;
import org.springframework.context.annotation.ComponentScan;
@SpringBootApplication

+ 0 - 27
app/app-iot-server/src/main/java/com/yihu/ehr/iot/config/ErrorPageConfig.java

@ -1,27 +0,0 @@
package com.yihu.ehr.iot.config;
import org.springframework.boot.context.embedded.ConfigurableEmbeddedServletContainer;
import org.springframework.boot.context.embedded.EmbeddedServletContainerCustomizer;
import org.springframework.boot.web.servlet.ErrorPage;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.HttpStatus;
/**
 * Created by progr1mmer on 2017/11/6.
 */
@Configuration
public class ErrorPageConfig {
    @Bean
    public EmbeddedServletContainerCustomizer containerCustomizer(){
        return new EmbeddedServletContainerCustomizer(){
            @Override
            public void customize(ConfigurableEmbeddedServletContainer container) {
                container.addErrorPages(new ErrorPage(HttpStatus.BAD_REQUEST, "/400"));
                container.addErrorPages(new ErrorPage(HttpStatus.INTERNAL_SERVER_ERROR, "/500"));
                container.addErrorPages(new ErrorPage(HttpStatus.NOT_FOUND, "/404"));
            }
        };
    }
}

+ 0 - 87
app/app-iot-server/src/main/java/com/yihu/ehr/iot/config/SpringSecurityConfig.java

@ -1,87 +0,0 @@
package com.yihu.ehr.iot.config;
import com.yihu.ehr.iot.security.AccessDecisionManagerImpl;
import com.yihu.ehr.iot.security.AccessDeniedHandlerImpl;
import org.springframework.context.annotation.Bean;
import org.springframework.security.access.AccessDecisionManager;
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.web.access.expression.DefaultWebSecurityExpressionHandler;
/**
 * @author lincl
 * @version 1.0
 * @created 2016/7/21
 */
@EnableWebSecurity
public class SpringSecurityConfig extends WebSecurityConfigurerAdapter {
    @Override
    public void configure(WebSecurity web) throws Exception {
        // 设置不拦截规则
        web.ignoring().antMatchers("/front/**");
    }
    @Override
    protected void configure(HttpSecurity http) throws Exception {
        // 设置拦截规则
        http.authorizeRequests().accessDecisionManager(accessDecisionManager())
                .expressionHandler(webSecurityExpressionHandler())
                .antMatchers("/login").permitAll()
                .antMatchers("/login/**").permitAll()
                .antMatchers("/**").hasRole("USER")
                .and()
                .exceptionHandling().accessDeniedHandler(accessDeniedHandler())
                .and()
                .headers().frameOptions().disable();//取消jfame的安全验证
        // 自定义登录页面
        http.csrf().disable().formLogin().loginPage("/login").permitAll();
        // 自定义注销
        //  http.logout().logoutUrl("/logout").logoutSuccessUrl("/login").invalidateHttpSession(true);
        // session管理
        //http.sessionManagement().sessionFixation().changeSessionId().maximumSessions(1).expiredUrl("/");
        // RemeberMe  和UserDetailsService合作 用来保存用户信息, 一段时间内可以不用在输入用户名和密码登录,暂不使用该功能
        //  http.rememberMe().key("webmvc#FD637E6D9C0F1A5A67082AF56CE32485");
    }
    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
    }
    /*
     * 最终访问控制器
     */
    @Bean(name = "accessDecisionManager")
    public AccessDecisionManager accessDecisionManager() {
        return new AccessDecisionManagerImpl();
    }
    /*
     * 错误信息拦截器
     */
    @Bean(name = "accessDeniedHandler")
    public AccessDeniedHandlerImpl accessDeniedHandler() {
        AccessDeniedHandlerImpl accessDeniedHandler = new AccessDeniedHandlerImpl();
        accessDeniedHandler.setErrorPage("/error/403.jsp");
        return accessDeniedHandler;
    }
    /*
     * 表达式控制器
     */
    @Bean(name = "expressionHandler")
    public DefaultWebSecurityExpressionHandler webSecurityExpressionHandler() {
        DefaultWebSecurityExpressionHandler webSecurityExpressionHandler = new DefaultWebSecurityExpressionHandler();
        return webSecurityExpressionHandler;
    }
}

+ 0 - 47
app/app-iot-server/src/main/java/com/yihu/ehr/iot/config/WebMvcConfig.java

@ -1,47 +0,0 @@
package com.yihu.ehr.iot.config;
import com.yihu.ehr.iot.interceptor.LoginInterceptor;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.PathMatchConfigurer;
import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;
/**
 * @author Sand
 * @version 1.0
 * @created 2016.03.03 21:50
 */
@Configuration
public class WebMvcConfig extends WebMvcConfigurerAdapter {
    @Autowired
    private LoginInterceptor loginInterceptor;
    /**
     * 注册拦截器
     */
    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        registry.addInterceptor(loginInterceptor).addPathPatterns("/**")
                .excludePathPatterns("/login/**", "/400", "/404", "/500");
        super.addInterceptors(registry);
    }
    /**
     * 配置路径完全匹配
     * idea版本 过低这样子映射boot启动会没有效果,只能tomcat启动  但是不影响打包
     * @param configurer
     */
    @Override
    public void configurePathMatch(PathMatchConfigurer configurer) {
        configurer.setUseSuffixPatternMatch(false)
                .setUseTrailingSlashMatch(true);
    }
//    @Override
//    public void addResourceHandlers(ResourceHandlerRegistry registry) {
//        registry.addResourceHandler("/front/**").addResourceLocations("classpath:/webapp/front/");
//    }
}

+ 4 - 2
app/app-iot-server/src/main/java/com/yihu/ehr/iot/controller/common/LoginController.java

@ -11,6 +11,7 @@ import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.*;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
@ -34,8 +35,9 @@ public class LoginController extends BaseController{
     */
    @RequestMapping(method = RequestMethod.GET)
    @ApiOperation(value = "登陆首页")
    public void index(HttpServletResponse response)throws IOException {
        response.sendRedirect(contextPath + "/front/views/login.html");
    public void index(HttpServletRequest request,HttpServletResponse response) throws IOException, ServletException {
//        response.sendRedirect(contextPath + "/front/views/login.html");
        request.getRequestDispatcher("/front/views/login.html").forward(request, response);
    }
    /**

+ 0 - 28
app/app-iot-server/src/main/java/com/yihu/ehr/iot/interceptor/LoginInterceptor.java

@ -1,28 +0,0 @@
package com.yihu.ehr.iot.interceptor;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
import org.springframework.web.servlet.handler.HandlerInterceptorAdapter;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
@Component
public class LoginInterceptor extends HandlerInterceptorAdapter {
    @Value("${server.contextPath}")
    protected String contextPath;
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
//        if(request.getRequestURL().indexOf("/ambulance/search")!=-1){
//            return true;
//        }
//        Boolean isLogin = (Boolean) request.getSession().getAttribute("isLogin");
//        if (isLogin == null || !isLogin) {
//            response.sendRedirect(contextPath+"/login");
//            response.setStatus(-200);
//            return false;
//        }
        return true;
    }
}

+ 0 - 99
app/app-iot-server/src/main/java/com/yihu/ehr/iot/security/AccessDecisionManagerImpl.java

@ -1,99 +0,0 @@
package com.yihu.ehr.iot.security;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.AccessDecisionManager;
import org.springframework.security.access.AccessDeniedException;
import org.springframework.security.access.ConfigAttribute;
import org.springframework.security.authentication.InsufficientAuthenticationException;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.web.FilterInvocation;
import java.util.Collection;
import java.util.Iterator;
/**
 * @author lincl
 * @version 1.0
 * @created 2016/7/22
 */
/**
 * Spring Security提供了一些拦截器,来控制对安全对象的访问权限,例如方法调用或web请求。
 * 一个是否允许执行调用的预调用决定,是由AccessDecisionManager实现的。
 * 这个 AccessDecisionManager 被AbstractSecurityInterceptor调用,
 * 它用来作最终访问控制的决定。
 */
public class AccessDecisionManagerImpl implements AccessDecisionManager {
    @Autowired
    private RoleCache roleCache;
    /**
     * 验证用户是否拥有权限
     * @param authentication 用户权限列表
     * @param object FilterInvocation 请求信息
     * @param configAttributes 当前访问路径所需权限
     * @throws AccessDeniedException 如无权限 抛出该异常
     * @throws InsufficientAuthenticationException
     */
    public void decide(Authentication authentication, Object object,
                       Collection<ConfigAttribute> configAttributes)
            throws AccessDeniedException, InsufficientAuthenticationException {
        if (configAttributes == null) {
            return;
        }
        FilterInvocation fi = (FilterInvocation) object;
        String url = fi.getRequestUrl();
        Iterator<ConfigAttribute> ite = configAttributes.iterator();
        ConfigAttribute ca;
        int index;
        while (ite.hasNext()) {
            ca = ite.next();
            if("anonymous".equals(ca.toString()) || "permitAll".equals(ca.toString())){
                return;
            }
        }
        index = url.indexOf("?");
        if(index!=-1)
            url = url.substring(0, index);
        url.replaceAll("/+", "/");
        if(!roleCache.contains(url))
            return;
        //ga 为用户所被赋予的权限
        if(authentication.getAuthorities().contains(new SimpleGrantedAuthority(url)))
            return;
        throw new AccessDeniedException("没有权限!");
    }
    /**
     * 在启动的时候被AbstractSecurityInterceptor调用,
     * 来决定AccessDecisionManager是否可以执行传递ConfigAttribute。
     * @param attribute
     * @return
     */
    public boolean supports(ConfigAttribute attribute) {
        return true;
    }
    /**
     * 被安全拦截器实现调用,
     * 包含安全拦截器将显示的AccessDecisionManager支持安全对象的类型。
     * @param clazz
     * @return
     */
    public boolean supports(Class<?> clazz) {
        return true;
    }
}

+ 0 - 60
app/app-iot-server/src/main/java/com/yihu/ehr/iot/security/AccessDeniedHandlerImpl.java

@ -1,60 +0,0 @@
package com.yihu.ehr.iot.security;
import com.yihu.ehr.iot.util.ControllerTools;
import org.springframework.security.access.AccessDeniedException;
import org.springframework.security.web.access.AccessDeniedHandler;
import javax.servlet.RequestDispatcher;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
/**
 * @author lincl
 * @version 1.0
 * @created 2016/7/22
 */
/**
 * 错误信息拦截器
 */
public class AccessDeniedHandlerImpl implements AccessDeniedHandler {
    private String errorPage;
    /**
     * 拦截错误信息, 并按逻辑返回错误到前端页面
     * @param request
     * @param response
     * @param accessDeniedException
     * @throws IOException
     * @throws ServletException
     */
    public void handle(HttpServletRequest request, HttpServletResponse response, AccessDeniedException accessDeniedException)
            throws IOException, ServletException {
        if(ControllerTools.isAjaxRequest(request)){
            response.setHeader("noPermission", "true");
            ControllerTools.print(response, "{}");
        }else if (!response.isCommitted()) {
            if (errorPage != null) {
                // Set the 403 status code.
                response.setStatus(HttpServletResponse.SC_FORBIDDEN);
                // forward to error page.
                RequestDispatcher dispatcher = request.getRequestDispatcher(errorPage);
                dispatcher.forward(request, response);
            } else {
                response.sendError(HttpServletResponse.SC_FORBIDDEN, accessDeniedException.getMessage());
            }
        }
    }
    public void setErrorPage(String errorPage) {
        if ((errorPage != null) && !errorPage.startsWith("/")) {
            throw new IllegalArgumentException("errorPage must begin with '/'");
        }
        this.errorPage = errorPage;
    }
}

+ 0 - 163
app/app-iot-server/src/main/java/com/yihu/ehr/iot/security/RoleCache.java

@ -1,163 +0,0 @@
package com.yihu.ehr.iot.security;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.yihu.ehr.iot.util.ObjectMapperUtil;
import com.yihu.ehr.iot.util.http.HttpHelper;
import com.yihu.ehr.iot.util.http.HttpResponse;
import com.yihu.ehr.util.rest.Envelop;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.CopyOnWriteArrayList;
/**
 * @author lincl
 * @version 1.0
 * @created 2016/7/22
 */
/**
 * �����ɫ��Ϣ
 */
@Service
public class RoleCache {
    //    private final static Map<String, CopyOnWriteArrayList<String>> resourceMap = new ConcurrentHashMap<>();
    @Value("${service-gateway.profileInnerUrl}")
    private String comUrl;
    @Value("${app.baseClientId}")
    private String baseClientId;
    @Autowired
    private ObjectMapper objectMapper;
    private final static CopyOnWriteArrayList<String> resourceList = new CopyOnWriteArrayList<>();
    //    private final static Set<String> resourceList = Collections.synchronizedSet(new HashSet<String>());
    public RoleCache() throws Exception {
        //loadRole();
    }
    private List<Map<String,Object>> getAppFeatures() throws Exception {
        Map params = new HashMap<>();
        String url = "/filterFeatureNoPage";
        params.put("filters", "appId=" + baseClientId);
        HttpResponse rs = HttpHelper.get(comUrl + url, params);
        //ObjectMapperUtil objectMapperUtil = new ObjectMapperUtil();
        Envelop envelop = (Envelop) ObjectMapperUtil.toModel(rs.getBody(), new TypeReference<Envelop>() {});
        return envelop.getDetailModelList();
        //return null;
    }
    public boolean contains(String url){
        return resourceList.contains(url);
    }
    public void addRes(String res){
        synchronized (resourceList){
            resourceList.add(res);
        }
    }
    public void removeRes(String res){
        synchronized (resourceList) {
            resourceList.remove(res);
        }
    }
    /**
     * ��ʼ�����Ȩ����Ϣ
     */
    //@PostConstruct
    private void loadRole() throws Exception {
        List<Map<String,Object>> appFeatureModelList = getAppFeatures();
        for(Map<String,Object> feature: appFeatureModelList){
            if(feature.get("url")!=null)
                resourceList.add(feature.get("url").toString());
        }
//        CopyOnWriteArrayList<String> cas = new CopyOnWriteArrayList<>();
//        cas.add("dataCenterAdmin");
//        resourceMap.put("appDel", cas );
//
//        cas = new CopyOnWriteArrayList<>();
//        cas.add("dataCenterAdmin");
//        resourceMap.put("/app/platform/initial", cas );
//
//        cas = new CopyOnWriteArrayList<>();
//        cas.add("dataCenterAdmin");
//        resourceMap.put("/app/platform/list", cas );
//
//        cas = new CopyOnWriteArrayList<>();
//        cas.add("admin2");
//        resourceMap.put("/app/api/initial", cas );
//
//        cas = new CopyOnWriteArrayList<>();
//        cas.add("admin2");
//        resourceMap.put("appAdd", cas );
    }
//    /**
//     * ��ȡ�ɷ���key��Դ�Ľ�ɫ
//     * @param key ��Դ
//     * @return ��ɫ��
//     */
//    public CopyOnWriteArrayList getConfigAttributes(String key){
//        return resourceMap.get(key);
//    }
//    /**
//     * �ж��Ƿ�ca�Ƿ񱻸���key����Ȩ��
//     * @param key ��Դ��Ϣ
//     * @param ca  ��ɫ
//     * @return
//     */
//    public boolean hasRole(String key, String ca){
//        Collection c = resourceMap.get(key);
//        if(c!=null)
//            return c.contains(ca);
//        return true;
//    }
//
//    /**
//     * �ж��Ƿ�ca�Ƿ񱻸���key����Ȩ��
//     * @param key ��Դ��Ϣ
//     * @param c  ��ɫ��
//     * @return
//     */
//    public boolean hasRole(String key, Collection<String> c) {
//        CopyOnWriteArrayList elements = resourceMap.get(key);
//        for (Object e: c) {
//            if(elements.indexOf(e)>=0)
//                return true;
//        }
//        return false;
//    }
//
//    /**
//     * ���Ȩ����Ϣ
//     * @param key ��Դ��Ϣ
//     * @param ca  ��ɫ
//     */
//    public void addCache(String key, String ca){
//        if(resourceMap.get(key)==null){
//            resourceMap.put(key, new CopyOnWriteArrayList<>());
//        }
//        resourceMap.get(key).add(ca);
//    }
//
//    /**
//     * ɾ��Ȩ����Ϣ
//     * @param key ��Դ��Ϣ
//     * @param ca ��ɫ
//     */
//    public void removeCache(String key, String ca){
//        if(resourceMap.get(key)!=null){
//            resourceMap.get(key).remove(ca);
//        }
//    }
}

+ 20 - 0
app/app-iot-server/src/main/java/com/yihu/ehr/iot/security/config/EhrWebHttpSessionConfiguration.java

@ -0,0 +1,20 @@
package com.yihu.ehr.iot.security.config;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.core.session.SessionRegistry;
import org.springframework.security.core.session.SessionRegistryImpl;
/**
 * Created by progr1mmer on 2018/1/27.
 */
//@Configuration
//@EnableRedisHttpSession
public class EhrWebHttpSessionConfiguration {
    /*
    @Bean
    SessionRegistry sessionRegistry(){
        return new SessionRegistryImpl();
    }*/
}

+ 106 - 0
app/app-iot-server/src/main/java/com/yihu/ehr/iot/security/config/EhrWebSecurityConfiguration.java

@ -0,0 +1,106 @@
package com.yihu.ehr.iot.security.config;
import com.yihu.ehr.iot.security.core.EhrWebAuthenticationProvider;
import com.yihu.ehr.iot.security.core.EhrWebAuthenticationSuccessHandler;
import com.yihu.ehr.iot.security.core.EhrWebUserDetailsService;
import com.yihu.ehr.iot.security.core.EhrWebUsernamePasswordAuthenticationFilter;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.authentication.encoding.Md5PasswordEncoder;
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.userdetails.UserDetailsService;
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;
/**
 * Created by progr1mmer on 2018/1/26.
 */
@Configuration
@EnableWebSecurity
public class EhrWebSecurityConfiguration extends WebSecurityConfigurerAdapter {
    @Value("${app.oauth2InnerUrl}")
    protected String oauth2InnerUrl;
    @Value("${service-gateway.profileInnerUrl}")
    protected String profileInnerUrl;
    @Autowired
    private EhrWebAuthenticationProvider ehrWebAuthenticationProvider;
    @Autowired
    private EhrWebAuthenticationSuccessHandler ehrWebAuthenticationSuccessHandler;
    //@Autowired
    //private EhrWebAccessDecisionManager ehrWebAccessDecisionManager;
    //@Autowired
    //private SessionRegistry sessionRegistry;
    @Override
    public void configure(WebSecurity web) throws Exception {
        //web.ignoring().antMatchers("/ambulance/search"); //忽略授权地址
    }
    @Override
    protected void configure(HttpSecurity http) throws Exception {
        // ---------- 自定义Filter Start ----------
        EhrWebUsernamePasswordAuthenticationFilter ehrWebUsernamePasswordAuthenticationFilter = new EhrWebUsernamePasswordAuthenticationFilter(oauth2InnerUrl, profileInnerUrl);
        ehrWebUsernamePasswordAuthenticationFilter.setAuthenticationSuccessHandler(ehrWebAuthenticationSuccessHandler);
        ehrWebUsernamePasswordAuthenticationFilter.setAuthenticationManager(authenticationManagerBean());
        //ehrWebUsernamePasswordAuthenticationFilter.setSessionAuthenticationStrategy(new ConcurrentSessionControlAuthenticationStrategy(sessionRegistry));
        http.addFilterBefore(ehrWebUsernamePasswordAuthenticationFilter, UsernamePasswordAuthenticationFilter.class);
        // ---------- 自定义Filter End ----------
        //http.sessionManagement().maximumSessions(3).expiredUrl("/login?expired").sessionRegistry(sessionRegistry);
        //http.addFilter(ehrWebUsernamePasswordAuthenticationFilter);
        http.authorizeRequests()
                //.accessDecisionManager(ehrWebAccessDecisionManager)
                //.antMatchers("/front/views/*.html").hasRole("USER") //拦截html
                //.antMatchers("/user").hasRole("USER")
                //.antMatchers("/ambulance/**").hasRole("USER")
                //.antMatchers("/admin/**").hasRole("ADMIN")
                .antMatchers("/front/css/**").permitAll()
                .antMatchers("/front/fonts/**").permitAll()
                .antMatchers("/front/images/**").permitAll()
                .antMatchers("/front/js/**").permitAll()
                .antMatchers("/front/views/signin.html").permitAll()
                .antMatchers("/login/**").permitAll()
                .antMatchers("/front/views/**").hasRole("USER")
                .antMatchers("/**").hasRole("USER")
                .and().formLogin().loginPage("/login")
                .and().logout().logoutUrl("/logout").logoutSuccessUrl("/login")
                .and().headers().frameOptions().disable()
                .and().csrf().disable();
    }
    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
        auth.authenticationProvider(ehrWebAuthenticationProvider); //自定义认证提供者
    }
    @Bean
    EhrWebUserDetailsService ehrWebUserDetailsService(){
        return new EhrWebUserDetailsService(profileInnerUrl);
    }
    @Bean
    EhrWebAuthenticationProvider ehrWebAuthenticationProvider(UserDetailsService userDetailsService) {
        EhrWebAuthenticationProvider ehrWebAuthenticationProvider = new EhrWebAuthenticationProvider(userDetailsService);
        ehrWebAuthenticationProvider.setPasswordEncoder(new Md5PasswordEncoder());
        return ehrWebAuthenticationProvider;
    }
    @Bean
    EhrWebAuthenticationSuccessHandler ehrWebAuthenticationSuccessHandler(){
        return new EhrWebAuthenticationSuccessHandler();
    }
    /**
    @Bean
    EhrWebAccessDecisionManager ehrWebAccessDecisionManager() {
        return new EhrWebAccessDecisionManager(null);
    }
    */
}

+ 95 - 0
app/app-iot-server/src/main/java/com/yihu/ehr/iot/security/core/EhrWebAccessDecisionManager.java

@ -0,0 +1,95 @@
package com.yihu.ehr.iot.security.core;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.context.MessageSource;
import org.springframework.context.support.MessageSourceAccessor;
import org.springframework.security.access.AccessDecisionManager;
import org.springframework.security.access.AccessDecisionVoter;
import org.springframework.security.access.AccessDeniedException;
import org.springframework.security.access.ConfigAttribute;
import org.springframework.security.access.vote.AbstractAccessDecisionManager;
import org.springframework.security.authentication.InsufficientAuthenticationException;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.SpringSecurityMessageSource;
import org.springframework.util.Assert;
import java.util.Collection;
import java.util.Iterator;
import java.util.List;
/**
 * Final AccessDecisionManager
 * Created by progr1mmer on 2018/1/26.
 */
public class EhrWebAccessDecisionManager extends AbstractAccessDecisionManager {
    private final Log logger = LogFactory.getLog(this.getClass());
    private List<AccessDecisionVoter<? extends Object>> decisionVoters;
    protected MessageSourceAccessor messages = SpringSecurityMessageSource.getAccessor();
    private boolean allowIfAllAbstainDecisions = false;
    public EhrWebAccessDecisionManager(List<AccessDecisionVoter<? extends Object>> decisionVoters) {
        super(decisionVoters);
        Assert.notEmpty(decisionVoters, "A list of AccessDecisionVoters is required");
        this.decisionVoters = decisionVoters;
    }
    @Override
    public void decide(Authentication authentication, Object o, Collection<ConfigAttribute> collection) throws AccessDeniedException, InsufficientAuthenticationException {
    }
    public void afterPropertiesSet() throws Exception {
        Assert.notEmpty(this.decisionVoters, "A list of AccessDecisionVoters is required");
        Assert.notNull(this.messages, "A message source must be set");
    }
    public List<AccessDecisionVoter<? extends Object>> getDecisionVoters() {
        return this.decisionVoters;
    }
    public boolean isAllowIfAllAbstainDecisions() {
        return this.allowIfAllAbstainDecisions;
    }
    public void setAllowIfAllAbstainDecisions(boolean allowIfAllAbstainDecisions) {
        this.allowIfAllAbstainDecisions = allowIfAllAbstainDecisions;
    }
    public void setMessageSource(MessageSource messageSource) {
        this.messages = new MessageSourceAccessor(messageSource);
    }
    public boolean supports(ConfigAttribute attribute) {
        Iterator var2 = this.decisionVoters.iterator();
        AccessDecisionVoter voter;
        do {
            if(!var2.hasNext()) {
                return false;
            }
            voter = (AccessDecisionVoter)var2.next();
        } while(!voter.supports(attribute));
        return true;
    }
    public boolean supports(Class<?> clazz) {
        Iterator var2 = this.decisionVoters.iterator();
        AccessDecisionVoter voter;
        do {
            if(!var2.hasNext()) {
                return true;
            }
            voter = (AccessDecisionVoter)var2.next();
        } while(voter.supports(clazz));
        return false;
    }
}

+ 156 - 0
app/app-iot-server/src/main/java/com/yihu/ehr/iot/security/core/EhrWebAuthenticationProvider.java

@ -0,0 +1,156 @@
package com.yihu.ehr.iot.security.core;
import org.springframework.security.authentication.BadCredentialsException;
import org.springframework.security.authentication.InternalAuthenticationServiceException;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.authentication.dao.AbstractUserDetailsAuthenticationProvider;
import org.springframework.security.authentication.dao.SaltSource;
import org.springframework.security.authentication.encoding.PasswordEncoder;
import org.springframework.security.authentication.encoding.PlaintextPasswordEncoder;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.core.session.SessionRegistry;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.util.Assert;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;
import javax.servlet.http.HttpServletRequest;
/**
 * Created by progr1mmer on 2018/1/26.
 */
public class EhrWebAuthenticationProvider extends AbstractUserDetailsAuthenticationProvider {
    private static final String USER_NOT_FOUND_PASSWORD = "userNotFoundPassword";
    private PasswordEncoder passwordEncoder;
    private String userNotFoundEncodedPassword;
    private SaltSource saltSource;
    private UserDetailsService userDetailsService;
    private SessionRegistry sessionRegistry;
    public EhrWebAuthenticationProvider() {
        this.setPasswordEncoder((PasswordEncoder)(new PlaintextPasswordEncoder()));
    }
    public EhrWebAuthenticationProvider(UserDetailsService userDetailsService) {
        this.userDetailsService = userDetailsService;
        this.setPasswordEncoder((PasswordEncoder)(new PlaintextPasswordEncoder()));
    }
    /**
    public EhrWebAuthenticationProvider(UserDetailsService userDetailsService, SessionRegistry sessionRegistry) {
        this.userDetailsService = userDetailsService;
        this.sessionRegistry = sessionRegistry;
        this.setPasswordEncoder((PasswordEncoder)(new PlaintextPasswordEncoder()));
    }
     */
    /**
     * Step 3
     * @param userDetails
     * @param authentication
     * @throws AuthenticationException
     */
    protected void additionalAuthenticationChecks(UserDetails userDetails, UsernamePasswordAuthenticationToken authentication) throws AuthenticationException {
        Object salt = null;
        if(this.saltSource != null) {
            salt = this.saltSource.getSalt(userDetails);
        }
        if(authentication.getCredentials() == null) {
            this.logger.debug("Authentication failed: no credentials provided");
            throw new BadCredentialsException(this.messages.getMessage("AbstractUserDetailsAuthenticationProvider.badCredentials", "Bad credentials"));
        } else {
            EhrWebAuthenticationToken ehrWebAuthenticationToken = (EhrWebAuthenticationToken) authentication;
            if(!ehrWebAuthenticationToken.isSso()) {
                String presentedPassword = authentication.getCredentials().toString();
                if (!this.passwordEncoder.isPasswordValid(userDetails.getPassword(), presentedPassword, salt)) {
                    this.logger.debug("Authentication failed: password does not match stored value");
                    throw new BadCredentialsException(this.messages.getMessage("AbstractUserDetailsAuthenticationProvider.badCredentials", "Bad credentials"));
                }
            }
            //HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
            //sessionRegistry.registerNewSession(request.getSession().getId(), userDetails);
        }
    }
    protected void doAfterPropertiesSet() throws Exception {
        Assert.notNull(this.userDetailsService, "A UserDetailsService must be set");
    }
    protected final UserDetails retrieveUser(String username, UsernamePasswordAuthenticationToken authentication) throws AuthenticationException {
        UserDetails loadedUser;
        try {
            loadedUser = this.getUserDetailsService().loadUserByUsername(username);
        } catch (UsernameNotFoundException var6) {
            if(authentication.getCredentials() != null) {
                String presentedPassword = authentication.getCredentials().toString();
                this.passwordEncoder.isPasswordValid(this.userNotFoundEncodedPassword, presentedPassword, (Object)null);
            }
            throw var6;
        } catch (Exception var7) {
            throw new InternalAuthenticationServiceException(var7.getMessage(), var7);
        }
        if(loadedUser == null) {
            throw new InternalAuthenticationServiceException("UserDetailsService returned null, which is an interface contract violation");
        } else {
            return loadedUser;
        }
    }
    public void setPasswordEncoder(Object passwordEncoder) {
        Assert.notNull(passwordEncoder, "passwordEncoder cannot be null");
        if(passwordEncoder instanceof PasswordEncoder) {
            this.setPasswordEncoder((PasswordEncoder)passwordEncoder);
        } else if(passwordEncoder instanceof org.springframework.security.crypto.password.PasswordEncoder) {
            final org.springframework.security.crypto.password.PasswordEncoder delegate = (org.springframework.security.crypto.password.PasswordEncoder)passwordEncoder;
            this.setPasswordEncoder(new PasswordEncoder() {
                public String encodePassword(String rawPass, Object salt) {
                    this.checkSalt(salt);
                    return delegate.encode(rawPass);
                }
                public boolean isPasswordValid(String encPass, String rawPass, Object salt) {
                    this.checkSalt(salt);
                    return delegate.matches(rawPass, encPass);
                }
                private void checkSalt(Object salt) {
                    Assert.isNull(salt, "Salt value must be null when used with crypto module PasswordEncoder");
                }
            });
        } else {
            throw new IllegalArgumentException("passwordEncoder must be a PasswordEncoder instance");
        }
    }
    private void setPasswordEncoder(PasswordEncoder passwordEncoder) {
        Assert.notNull(passwordEncoder, "passwordEncoder cannot be null");
        this.userNotFoundEncodedPassword = passwordEncoder.encodePassword("userNotFoundPassword", (Object)null);
        this.passwordEncoder = passwordEncoder;
    }
    protected PasswordEncoder getPasswordEncoder() {
        return this.passwordEncoder;
    }
    public void setSaltSource(SaltSource saltSource) {
        this.saltSource = saltSource;
    }
    protected SaltSource getSaltSource() {
        return this.saltSource;
    }
    public void setUserDetailsService(UserDetailsService userDetailsService) {
        this.userDetailsService = userDetailsService;
    }
    protected UserDetailsService getUserDetailsService() {
        return this.userDetailsService;
    }
}

+ 51 - 0
app/app-iot-server/src/main/java/com/yihu/ehr/iot/security/core/EhrWebAuthenticationSuccessHandler.java

@ -0,0 +1,51 @@
package com.yihu.ehr.iot.security.core;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.yihu.ehr.util.rest.Envelop;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.MediaType;
import org.springframework.security.core.Authentication;
import org.springframework.security.web.authentication.AuthenticationSuccessHandler;
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;
/**
 * Created by progr1mmer on 2018/1/26.
 */
public class EhrWebAuthenticationSuccessHandler implements AuthenticationSuccessHandler {
    @Autowired
    private ObjectMapper objectMapper;
    //@Autowired
    //private FindByIndexNameSessionRepository findByIndexNameSessionRepository;
    /**
     * Step 4
     * @param httpServletRequest
     * @param httpServletResponse
     * @param authentication
     * @throws IOException
     * @throws ServletException
     */
    @Override
    public void onAuthenticationSuccess(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Authentication authentication) throws IOException, ServletException {
        Envelop envelop = new Envelop();
        envelop.setSuccessFlg(true);
        Map userMap = new HashMap();
        String id = (String) httpServletRequest.getAttribute("id");
        String username = (String) httpServletRequest.getAttribute("username");
        String realName = (String) httpServletRequest.getAttribute("realName");
        userMap.put("id", id);
        userMap.put("username", username);
        userMap.put("realName", realName);
        envelop.setObj(userMap);
        //Map<String, Object> sessionMap = findByIndexNameSessionRepository.findByIndexNameAndIndexValue(FindByIndexNameSessionRepository.PRINCIPAL_NAME_INDEX_NAME, "admin");
        httpServletResponse.setContentType(MediaType.APPLICATION_JSON_UTF8_VALUE);
        httpServletResponse.getWriter().print(objectMapper.writeValueAsString(envelop));
    }
}

+ 54 - 0
app/app-iot-server/src/main/java/com/yihu/ehr/iot/security/core/EhrWebAuthenticationToken.java

@ -0,0 +1,54 @@
package com.yihu.ehr.iot.security.core;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.SpringSecurityCoreVersion;
import java.util.Collection;
/**
 * Sso integrated
 * Created by progr1mmer on 2018/1/27.
 */
public class EhrWebAuthenticationToken extends UsernamePasswordAuthenticationToken {
    private static final long serialVersionUID = SpringSecurityCoreVersion.SERIAL_VERSION_UID;
    // ~ Instance fields
    // ================================================================================================
    private final Object principal;
    private Object credentials;
    private boolean isSso;
    // ~ Constructors
    // ===================================================================================================
    /**
     * This constructor can be safely used by any code that wishes to create a
     * <code>UsernamePasswordAuthenticationToken</code>, as the {@link #isAuthenticated()}
     * will return <code>false</code>.
     *
     */
        public EhrWebAuthenticationToken(Object principal, Object credentials, boolean isSso) {
        super(principal, credentials);
        this.principal = principal;
        this.credentials = credentials;
        this.isSso = isSso;
        setAuthenticated(false);
    }
    public boolean isSso() {
        return this.isSso;
    }
    @Override
    public Object getPrincipal() {
        return principal;
    }
    @Override
    public Object getCredentials() {
        return credentials;
    }
}

+ 47 - 0
app/app-iot-server/src/main/java/com/yihu/ehr/iot/security/core/EhrWebUserDetails.java

@ -0,0 +1,47 @@
package com.yihu.ehr.iot.security.core;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.userdetails.UserDetails;
import java.util.Collection;
/**
 * Created by progr1mmer on 2018/1/26.
 */
public class EhrWebUserDetails implements UserDetails {
    @Override
    public Collection<? extends GrantedAuthority> getAuthorities() {
        return null;
    }
    @Override
    public boolean isEnabled() {
        return false;
    }
    @Override
    public boolean isCredentialsNonExpired() {
        return false;
    }
    @Override
    public String getPassword() {
        return null;
    }
    @Override
    public String getUsername() {
        return null;
    }
    @Override
    public boolean isAccountNonExpired() {
        return false;
    }
    @Override
    public boolean isAccountNonLocked() {
        return false;
    }
}

+ 86 - 0
app/app-iot-server/src/main/java/com/yihu/ehr/iot/security/core/EhrWebUserDetailsService.java

@ -0,0 +1,86 @@
package com.yihu.ehr.iot.security.core;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.yihu.ehr.agModel.user.UserDetailModel;
import com.yihu.ehr.iot.util.http.HttpHelper;
import com.yihu.ehr.iot.util.http.HttpResponse;
import com.yihu.ehr.util.rest.Envelop;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.core.session.SessionRegistry;
import org.springframework.security.core.userdetails.User;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
//import org.springframework.session.FindByIndexNameSessionRepository;
import org.springframework.util.Assert;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;
import javax.servlet.http.HttpServletRequest;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.Map;
/**
 * Created by progr1mmer on 2018/1/26.
 */
public class EhrWebUserDetailsService implements UserDetailsService {
    private final Logger logger = LoggerFactory.getLogger(this.getClass());
    private final ObjectMapper objectMapper = new ObjectMapper();
    private final String profileInnerUrl;
    public EhrWebUserDetailsService(String profileInnerUrl){
        Assert.hasText(profileInnerUrl, "ProfileInnerUrl must not be empty or null");
        this.profileInnerUrl = profileInnerUrl;
    }
    /**
     * Step 2
     * @param username
     * @return
     * @throws UsernameNotFoundException
     */
    @Override
    public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
        try {
            Map<String, Object> params = new HashMap<>();
            params.put("login_code", username);
            HttpResponse httpResponse = HttpHelper.get(profileInnerUrl + "/users/" + username, params);
            if(httpResponse.getStatusCode() == 200) {
                Envelop envelop = this.objectMapper.readValue(httpResponse.getBody(), Envelop.class);
                if (envelop.isSuccessFlg()){
                    String user = this.objectMapper.writeValueAsString(envelop.getObj());
                    UserDetailModel userDetailModel = this.objectMapper.readValue(user, UserDetailModel.class);
                    String password = userDetailModel.getPassword();
                    HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
                    //登陆成功后需要的属性
                    request.setAttribute("id", userDetailModel.getId());
                    request.setAttribute("username", username);
                    request.setAttribute("realName", userDetailModel.getRealName());
                    return new User(username, password, getGrantedAuthorities(username));
                }
                logger.error(httpResponse.getBody());
                logger.error(envelop.getErrorMsg());
            }
        }catch (Exception e) {
            e.printStackTrace();
        }
        throw new UsernameNotFoundException(username);
    }
    private Collection<GrantedAuthority> getGrantedAuthorities(String username) {
        Collection<GrantedAuthority> authorities = new ArrayList<>(1);
        authorities.add(new SimpleGrantedAuthority("ROLE_USER"));
        return authorities;
    }
}

+ 178 - 0
app/app-iot-server/src/main/java/com/yihu/ehr/iot/security/core/EhrWebUsernamePasswordAuthenticationFilter.java

@ -0,0 +1,178 @@
package com.yihu.ehr.iot.security.core;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.yihu.ehr.agModel.user.UserDetailModel;
import com.yihu.ehr.iot.util.http.HttpHelper;
import com.yihu.ehr.iot.util.http.HttpResponse;
import com.yihu.ehr.util.rest.Envelop;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.security.authentication.AuthenticationServiceException;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.web.authentication.AbstractAuthenticationProcessingFilter;
import org.springframework.security.web.util.matcher.AntPathRequestMatcher;
import org.springframework.util.Assert;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.HashMap;
import java.util.Map;
/**
 * Sso integrated
 * Created by progr1mmer on 2018/1/27.
 */
public class EhrWebUsernamePasswordAuthenticationFilter extends AbstractAuthenticationProcessingFilter {
    private static Logger logger = LoggerFactory.getLogger(EhrWebUsernamePasswordAuthenticationFilter.class);
    public static final String SPRING_SECURITY_FORM_USERNAME_KEY = "username";
    public static final String SPRING_SECURITY_FORM_PASSWORD_KEY = "password";
    private ObjectMapper objectMapper = new ObjectMapper();
    private String usernameParameter = "username";
    private String passwordParameter = "password";
    private String clientIdParameter = "clientId";
    private String accessTokenParameter = "accessToken";
    private boolean postOnly = true;
    private final String oauth2InnerUrl;
    private final String profileInnerUrl;
    public EhrWebUsernamePasswordAuthenticationFilter(String oauth2InnerUrl, String profileInnerUrl) {
        super(new AntPathRequestMatcher("/login", "POST"));
        Assert.hasText(oauth2InnerUrl, "Oauth2InnerUrl must not be empty or null");
        Assert.hasText(profileInnerUrl, "ProfileInnerUrl must not be empty or null");
        this.oauth2InnerUrl = oauth2InnerUrl;
        this.profileInnerUrl = profileInnerUrl;
    }
    /**
     * Step 1
     * @param request
     * @param response
     * @return
     * @throws AuthenticationException
     */
    public Authentication attemptAuthentication(HttpServletRequest request, HttpServletResponse response) throws AuthenticationException {
        if(this.postOnly && !request.getMethod().equals("POST")) {
            throw new AuthenticationServiceException("Authentication method not supported: " + request.getMethod());
        } else {
            String username = null;
            String password = null;
            if(isSso(request)) {
                Map<String, Object> params = new HashMap<>();
                params.put("clientId", this.obtainClientId(request));
                params.put("accessToken", this.obtainAccessToken(request));
                try {
                    HttpResponse httpResponse = HttpHelper.post(oauth2InnerUrl + "/oauth/validToken", params);
                    if(httpResponse.getStatusCode() == 200) {
                        Map<String, Object> map = objectMapper.readValue(httpResponse.getBody(), Map.class);
                        if ((Boolean) map.get("successFlg")) {
                            String loginName = (String) map.get("user");
                            //验证通过。赋值session中的用户信息
                            params.clear();
                            params.put("login_code", loginName);
                            httpResponse = HttpHelper.get(profileInnerUrl + "/users/" + loginName, params);
                            Envelop envelop = this.objectMapper.readValue(httpResponse.getBody(), Envelop.class);
                            String user = this.objectMapper.writeValueAsString(envelop.getObj());
                            UserDetailModel userDetailModel = this.objectMapper.readValue(user, UserDetailModel.class);
                            username = userDetailModel.getLoginCode();
                            password = userDetailModel.getPassword();
                        }
                    }else {
                        logger.error(httpResponse.getBody());
                    }
                }catch (Exception e) {
                    e.printStackTrace();
                }
            }else {
                username = this.obtainUsername(request);
                password = this.obtainPassword(request);
            }
            if(username == null) {
                username = "";
            }
            if(password == null) {
                password = "";
            }
            username = username.trim();
            UsernamePasswordAuthenticationToken authRequest = new EhrWebAuthenticationToken(username, password, isSso(request)); //单点登陆集成
            this.setDetails(request, authRequest);
            return this.getAuthenticationManager().authenticate(authRequest);
        }
    }
    //单点登陆集成 ------------ Start -------------
    protected String obtainClientId(HttpServletRequest request) {
        return request.getParameter(this.clientIdParameter);
    }
    protected String obtainAccessToken(HttpServletRequest request) {
        return request.getParameter(this.accessTokenParameter);
    }
    //单点登陆集成 ------------ End -------------
    protected String obtainPassword(HttpServletRequest request) {
        return request.getParameter(this.passwordParameter);
    }
    protected String obtainUsername(HttpServletRequest request) {
        return request.getParameter(this.usernameParameter);
    }
    public void setPostOnly(boolean postOnly) {
        this.postOnly = postOnly;
    }
    protected void setDetails(HttpServletRequest request, UsernamePasswordAuthenticationToken authRequest) {
        authRequest.setDetails(this.authenticationDetailsSource.buildDetails(request));
    }
    //单点登陆集成 ------------ Start -------------
    public void setClientIdParameter(String clientIdParameter) {
        Assert.hasText(clientIdParameter, "ClientId parameter must not be empty or null");
        this.clientIdParameter = clientIdParameter;
    }
    public void setAccessTokenParameter(String accessTokenParameter) {
        Assert.hasText(accessTokenParameter, "AccessTokenParameter parameter must not be empty or null");
        this.accessTokenParameter = accessTokenParameter;
    }
    //单点登陆集成 ------------ End -------------
    public void setUsernameParameter(String usernameParameter) {
        Assert.hasText(usernameParameter, "Username parameter must not be empty or null");
        this.usernameParameter = usernameParameter;
    }
    public void setPasswordParameter(String passwordParameter) {
        Assert.hasText(passwordParameter, "Password parameter must not be empty or null");
        this.passwordParameter = passwordParameter;
    }
    public final String getClientIdParameter() {
        return this.clientIdParameter;
    }
    public final String getAccessTokenParameter() {
        return this.accessTokenParameter;
    }
    public final String getUsernameParameter() {
        return this.usernameParameter;
    }
    public final String getPasswordParameter() {
        return this.passwordParameter;
    }
    private boolean isSso(HttpServletRequest request){
        return null != request.getParameter(accessTokenParameter);
    }
}

+ 18 - 12
app/app-iot-server/src/main/resources/application.yml

@ -20,13 +20,17 @@ spring:
  application:
    name: app-emergency-server
    message: EHR Emergency Server
  resources:
    static-locations: classpath:/
    cache-period: 0
permissions:
  info: admin
app:
  clientId: 3CDhsgepr4
  baseClientId: Qz2yA1MOD0  # 【物联网】应用
  clientId: Qz2yA1MOD0 # 【物联网】应用
fast-dfs:
  tracker-server: 172.19.103.54:22122 #服务器地址
@ -44,21 +48,23 @@ fast-dfs:
---
spring:
  profiles: dev
  profiles: jwdev
  loginVaild: true
  redis:
    host: 172.19.103.47 # Redis server host.
    port: 6379
    password: redis!@456
app:
  oauth2InnerUrl: http://172.19.103.44:10260/
  oauth2OuterUrl: http://27.154.233.186:10260/  #上饶-授权外网映射
#  oauth2InnerUrl: http://172.19.103.44:10260/  # 物联网环境
  oauth2InnerUrl: http://172.19.103.73:10260/   # 认证中心,获取token ehr环境
  oauth2OuterUrl: http://27.154.233.186:10260/  # 上饶-授权外网映射
service-gateway:
  iotUrl: http://192.168.131.24:8088/svr-iot/
  profileInnerUrl: http://172.19.103.48:10000/api/v1.0/admin
  iotUrl: http://192.168.131.24:8088/svr-io
#  profileInnerUrl: http://172.19.103.48:10000/api/v1.0/admin/ # 物联网环境
  profileInnerUrl: http://172.19.103.73:10000/api/v1.0/admin   # 网关接口 ehr环境
  profileOuterUrl: http://27.154.233.186:10000/api/v1.0/admin
  portalInnerUrl: http://172.19.103.48:10280/api/v1.0/portal
  portalOuterUrl: http://27.154.233.186:10280/api/v1.0/portal
fast-dfs:
  tracker-server: 172.19.103.54:22122
  public-server: http://172.19.103.54:80/
@ -68,7 +74,7 @@ logging:
---
spring:
  profiles: test
  profiles: jwtest
  loginVaild: true
  redis:
    host: 172.19.103.47 # Redis server host.
@ -87,11 +93,11 @@ fast-dfs:
  public-server: http://172.19.103.54:80/
logging:
  path: /data/logger
  file: app-emergency-server
  file: app-iot-server
---
spring:
  profiles: prod
  profiles: jwprod
  loginVaild: true
  redis:
    host: 172.19.103.47 # Redis server host.

+ 2 - 2
app/app-iot-server/src/main/webapp/front/js/common/apiServer.js

@ -65,10 +65,10 @@ define(['jquery', 'promise', 'layer', 'jsHelper'], function ($, Promise, layer,
            return baseUrl + 'attendance/index'
        },
        autoLogin: function (opt) {//单点登录
            return httpPost(baseUrl + 'login/autoLogin', opt)
            return httpPost(baseUrl + 'login', opt)
        },
        login: function(opt) {//登录
            return httpPost(baseUrl + 'login/submit', opt)
            return httpPost(baseUrl + 'login11', opt)
        },
        out: function (opt) {//退出
            sessionStorage.clear();

+ 1 - 1
app/app-iot-server/src/main/webapp/front/js/common/config.js

@ -3,7 +3,7 @@
 */
require.config({
    urlArgs: 'bust=' +  (new Date()).getTime(),//测试打开
    baseUrl: '../js',
    baseUrl: '/iot/front/js/',
    paths: {
        'jquery': 'lib/jquery.min',
        'bootstrap': 'lib/bootstrap.min',

+ 1 - 1
app/app-iot-server/src/main/webapp/front/js/scripts/login.js

@ -29,7 +29,7 @@ require(loginRelyOn, function ($, layer, vue, jsHelper, apiServer, Promise) {
                this.setLoad();
                apiServer.login({
                    data:{
                        "userName": this.userID,
                        "username": this.userID,
                        "password": this.password
                    }
                }).then(function (res) {

+ 1 - 1
app/app-iot-server/src/main/webapp/front/js/scripts/signin.js

@ -31,7 +31,7 @@ require([
            var me = this;
            apiServer.autoLogin({
                data: {
                    "token":token,
                    "accessToken":token,
                    "clientId": clientId
                }
            }).then(function (data) {

+ 7 - 7
app/app-iot-server/src/main/webapp/front/views/login.html

@ -1,12 +1,12 @@
<!DOCTYPE html>
<html>
<html xmlns:v-on="http://www.w3.org/1999/xhtml">
    <head>
        <meta charset="utf-8">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <title>登录</title>
        <link href="../css/bootstrap.min14ed.css" rel="stylesheet">
        <link href="../css/style.min862f.css" rel="stylesheet">
        <link href="../css/login.css" rel="stylesheet">
        <link href="/iot/front/css/bootstrap.min14ed.css" rel="stylesheet">
        <link href="/iot/front/css/style.min862f.css" rel="stylesheet">
        <link href="/iot/front/css/login.css" rel="stylesheet">
        <!--[if lt IE 9]>
        <meta http-equiv="refresh" content="0;ie.html" />
        <![endif]-->
@ -47,8 +47,8 @@
        </div>
        <script src="../js/lib/plugins/require/require.js"></script>
        <script src="../js/common/config.js"></script>
        <script src="../js/scripts/login.js"></script>
        <script src="/iot/front/js/lib/plugins/require/require.js"></script>
        <script src="/iot/front/js/common/config.js"></script>
        <script src="/iot/front/js/scripts/login.js"></script>
    </body>
</html>

+ 3 - 2
svr/svr-manage/src/main/java/com/yihu/jw/manage/controller/wechat/GraphicMessageController.java

@ -1,9 +1,10 @@
package com.yihu.jw.manage.controller.wechat;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.yihu.jw.base.wx.WxGraphicMessageDO;
import com.yihu.jw.manage.service.wechat.GraphicMessageService;
import com.yihu.jw.restmodel.common.Envelop;
import com.yihu.jw.restmodel.base.wx.MWxGraphicMessage;
import com.yihu.jw.restmodel.base.wx.WxGraphicMessageVO;
import com.yihu.jw.rm.base.WechatRequestMapping;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
@ -73,7 +74,7 @@ public class GraphicMessageController {
    @PostMapping(value = WechatRequestMapping.WxGraphicMessage.api_create)
    @ApiOperation(value = "保存或者修改微信图文消息", notes = "保存或者修改微信图文消息")
    public Envelop saveOrUpdate(@ModelAttribute @Valid MWxGraphicMessage graphicMessage,@RequestParam String userCode) throws JsonProcessingException {
    public Envelop saveOrUpdate(@ModelAttribute @Valid WxGraphicMessageDO graphicMessage, @RequestParam String userCode) throws JsonProcessingException {
        return graphicMessageService.saveOrUpdate(graphicMessage,userCode);
    }
}

+ 3 - 2
svr/svr-manage/src/main/java/com/yihu/jw/manage/controller/wechat/WechatMenuController.java

@ -1,9 +1,10 @@
package com.yihu.jw.manage.controller.wechat;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.yihu.jw.base.wx.WxMenuDO;
import com.yihu.jw.manage.service.wechat.WechatMenuService;
import com.yihu.jw.restmodel.common.Envelop;
import com.yihu.jw.restmodel.base.wx.MWxMenu;
import com.yihu.jw.restmodel.base.wx.WxMenuVO;
import com.yihu.jw.rm.base.WechatRequestMapping;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
@ -82,7 +83,7 @@ public class WechatMenuController {
    @PostMapping(value = WechatRequestMapping.WxMenu.api_create)
    @ApiOperation(value = "保存或者修改微信菜单", notes = "保存或者修改微信菜单")
    public Envelop saveOrUpdate(@ModelAttribute @Valid MWxMenu menu,@RequestParam String userCode) throws JsonProcessingException {
    public Envelop saveOrUpdate(@ModelAttribute @Valid WxMenuDO menu, @RequestParam String userCode) throws JsonProcessingException {
        Envelop envelop = menuService.saveOrUpdate(menu,userCode);
        return envelop;
    }