欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

微服務Redis-Session共享登錄狀態(tài)的過程詳解

 更新時間:2023年12月18日 09:24:37   作者:無敵小田田  
這篇文章主要介紹了微服務Redis-Session共享登錄狀態(tài),本文采取Spring security做登錄校驗,用redis做session共享,實現(xiàn)單服務登錄可靠性,微服務之間調(diào)用的可靠性與通用性,需要的朋友可以參考下

一、背景

        隨著項目越來越大,需要將多個服務拆分成微服務,使代碼看起來不要過于臃腫,龐大。微服務之間通常采取feign交互,為了保證不同微服務之間增加授權校驗,需要增加Spring Security登錄驗證,為了多個服務之間session可以共享,可以通過數(shù)據(jù)庫實現(xiàn)session共享,也可以采用redis-session實現(xiàn)共享。

        本文采取Spring security做登錄校驗,用redis做session共享。實現(xiàn)單服務登錄可靠性,微服務之間調(diào)用的可靠性與通用性

二、代碼

本文項目采取 主服務一服務、子服務二 來舉例

1、服務依賴文件

主服務依賴

    implementation group: 'org.springframework.boot', name: 'spring-boot-starter-data-redis', version: '2.5.4'
    implementation group: 'org.springframework.session', name: 'spring-session-data-redis', version: '2.4.1'
    implementation(group: 'io.github.openfeign', name: 'feign-httpclient')
    implementation 'org.springframework.boot:spring-boot-starter-security'

子服務依賴

    implementation group: 'org.springframework.boot', name: 'spring-boot-starter-data-redis', version: '2.5.4'
    implementation group: 'org.springframework.session', name: 'spring-session-data-redis', version: '2.4.1'
    implementation 'org.springframework.boot:spring-boot-starter-security'

2、服務配置文件

主服務配置文件

#redis連接

spring.redis.host=1.2.3.4

#Redis服務器連接端口

spring.redis.port=6379

#Redis服務器連接密碼

spring.redis.password=password

#連接池最大連接數(shù)(使用負值表示沒有限制)

spring.redis.pool.max-active=8

#連接池最大阻塞等待時間(使用負值表示沒有限制)

spring.redis.pool.max-wait=-1

#連接池中的最大空閑連接

spring.redis.pool.max-idle=8

#連接池中的最小空閑連接

spring.redis.pool.min-idle=0

#連接超時時間(毫秒)

spring.redis.timeout=30000

#數(shù)據(jù)庫

spring.redis.database=0

#redis-session配置

spring.session.store-type=redis

#部分post請求過長會報錯,需加配置

server.tomcat.max-http-header-size=65536

子服務配置文件

#單獨登錄秘鑰

micService.username=service

micService.password=aaaaaaaaaaaaa

#登錄白名單

micService.ipList=1.2.3.4,1.2.3.5,127.0.0.1,0:0:0:0:0:0:0:1

spring.redis.host=1.2.3.4

#Redis服務器連接端口

spring.redis.port=6379

#Redis服務器連接密碼

spring.redis.password=password

#連接池最大連接數(shù)(使用負值表示沒有限制)

spring.redis.pool.max-active=8

#連接池最大阻塞等待時間(使用負值表示沒有限制)

spring.redis.pool.max-wait=-1

#連接池中的最大空閑連接

spring.redis.pool.max-idle=8

#連接池中的最小空閑連接

spring.redis.pool.min-idle=0

#連接超時時間(毫秒)

spring.redis.timeout=30000

#數(shù)據(jù)庫

spring.redis.database=0

#最大請求頭限制

server.maxPostSize=-1

server.maxHttpHeaderSize=102400

#redis session緩存

spring.session.store-type=redis

server.servlet.session.timeout=30m

3、登錄校驗文件

主服務SecurityConfig.java

@Configuration
@EnableWebSecurity
@EnableGlobalMethodSecurity(prePostEnabled = true)
public class SecurityConfig extends WebSecurityConfigurerAdapter {
    //注入密碼加密的類
    @Bean
    public AuthenticationProvider authenticationProvider() {
        AuthenticationProvider authenticationProvider = new EncoderProvider();
        return authenticationProvider;
    }
    @Autowired
    public void configureGlobalSecurity(AuthenticationManagerBuilder auth) throws Exception {
        auth.userDetailsService(userDetailsService);
        auth.authenticationProvider(authenticationProvider());
    }
    public static final Logger logger = LoggerFactory.getLogger(SecurityConfig.class);
    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http.formLogin()
                .successHandler((request,response,authentication) -> {
                    HttpSession session = request.getSession();
                    session.setAttribute("TaobaoUser",authentication.getPrincipal());
                    ObjectMapper mapper = new ObjectMapper();
                    response.setContentType("application/json;charset=utf-8");
                    PrintWriter out = response.getWriter();
                    TaobaoUser user = (CurrentUser)session.getAttribute("TaobaoUser");
                    out.write(mapper.writeValueAsString(user));
                    out.flush();
                    out.close();
                })
                .failureHandler((request,response,authentication) -> {
                    ObjectMapper mapper = new ObjectMapper();
                    response.setContentType("application/json;charset=utf-8");
                    PrintWriter out = response.getWriter();
                    out.write(mapper.writeValueAsString(new ExceptionMessage("400",authentication.getMessage())));
                    out.flush();
                    out.close();
                })
                .loginPage("/Login.html")
                .loginProcessingUrl("/login")
                .and()
                .authorizeRequests()
                .antMatchers("/api/common/invalidUrl","/**/*.css", "/**/*.js", "/**/*.gif ", "/**/*.png ", "/**/*.jpg", "/webjars/**", "**/favicon.ico", "/guestAccess", "/Login.html",
                        "/v2/api-docs","/configuration/security","/configuration/ui","/api/common/CheckLatestVersionInfo").permitAll()
                .anyRequest()
                //任何請求
                .authenticated()
                .and()
                .sessionManagement()
                .maximumSessions(-1)
                .sessionRegistry(sessionRegistry());
        ;
        http.csrf().disable();
    }
    @Autowired
    private FindByIndexNameSessionRepository sessionRepository;
    @Bean
    public SpringSessionBackedSessionRegistry sessionRegistry(){
        return new SpringSessionBackedSessionRegistry(sessionRepository);
    }
}

EncoderProvider.java

@Service
public class EncoderProvider implements AuthenticationProvider {
    public static final Logger logger = LoggerFactory.getLogger(EncoderProvider.class);
    /**
     * 自定義驗證方式
     */
    @Override
    public Authentication authenticate(Authentication authentication) throws AuthenticationException {
        try {
            //支持用戶名和員工號登錄 可能為用戶名或員工號
            String username = authentication.getName();
            String credential = (String) authentication.getCredentials();
            //加密過程在這里體現(xiàn)
            TaobaoUser user= userService.getUserData(username);
            //校驗,用戶名是否存在
            if(user==null){
                throw new DisabledException("用戶名或密碼錯誤");
            }
            //校驗登錄狀態(tài)
            checkPassword()
            Collection<GrantedAuthority> authorities = new ArrayList<>();
            return new UsernamePasswordAuthenticationToken(userCurrent, credential, authorities);
        } catch (Exception ex) {
            ex.printStackTrace();
            throw new DisabledException("登錄發(fā)生錯誤 : " + ex.getMessage());
        }
    }
    @Override
    public boolean supports(Class<?> arg0) {
        return true;
    }

子服務SecurityConfig.java

@Configuration
@EnableWebSecurity
@EnableGlobalMethodSecurity(prePostEnabled = true)
public class SecurityConfig extends WebSecurityConfigurerAdapter {
    //注入密碼加密的類
    @Bean
    public AuthenticationProvider authenticationProvider() {
        AuthenticationProvider authenticationProvider = new EncoderProvider();
        return authenticationProvider;
    }
    @Autowired
    public void configureGlobalSecurity(AuthenticationManagerBuilder auth) throws Exception {
        auth.authenticationProvider(authenticationProvider());
    }
    public static final Logger logger = LoggerFactory.getLogger(SecurityConfig.class);
    @Override
    protected void configure(HttpSecurity http) throws Exception {
        logger.info("用戶登錄日志test1 username:"+http.toString());
                http.formLogin()
                    .loginProcessingUrl("/login")
                    .successHandler((request,response,authentication) -> {
                    HttpSession session = request.getSession();
                    session.setAttribute("TaobaoUser",authentication.getPrincipal());
                    ObjectMapper mapper = new ObjectMapper();
                    response.setContentType("application/json;charset=utf-8");
                    PrintWriter out = response.getWriter();
                    TaobaoUser user = (TaobaoUser )session.getAttribute("TaobaoUser");
                    out.write(mapper.writeValueAsString(user));
                    out.flush();
                    out.close();
                })
                .failureHandler((request,response,authentication) -> {
                    ObjectMapper mapper = new ObjectMapper();
                    response.setContentType("application/json;charset=utf-8");
                    PrintWriter out = response.getWriter();
                    out.write(mapper.writeValueAsString(new ExceptionMessage("400",authentication.getMessage())));
                    out.flush();
                    out.close();
                })
                .loginPage("/Login.html")
                .and()
                .authorizeRequests()
                .antMatchers("/**/*.css", "/**/*.js", "/**/*.gif ", "/**/*.png ",
                        "/**/*.jpg", "/webjars/**", "**/favicon.ico", "/Login.html",
                        "/v2/api-docs","/configuration/security","/configuration/ui").permitAll()
                .anyRequest().authenticated()
                .and()
                .sessionManagement()
                .maximumSessions(-1)
                .sessionRegistry(sessionRegistry());
        http.csrf().disable();
    }
    @Autowired
    private FindByIndexNameSessionRepository sessionRepository;
    @Bean
    public SpringSessionBackedSessionRegistry sessionRegistry(){
        return new SpringSessionBackedSessionRegistry(sessionRepository);
    }
}

EncoderProvider.java

@Service
public class EncoderProvider implements AuthenticationProvider {
    public static final Logger logger = LoggerFactory.getLogger(EncoderProvider.class);
    @Value("${service.username}")
    private String  userName1;
    @Value("${service.ipList}")
    private String  ipList;
    /**
     * 自定義驗證方式
     */
    @Override
    public Authentication authenticate(Authentication authentication) throws AuthenticationException {
        try {
            //支持用戶名和員工號登錄 可能為用戶名或員工號
            String username = authentication.getName();
            String credential = (String)authentication.getCredentials();
            TaobaoUser user=new TaobaoUser();
            if(username.equals(userName1)){
                  List<String> ips = Arrays.asList(ipList.split(","));
                  WebAuthenticationDetails details = (WebAuthenticationDetails) authentication.getDetails();
                  String remoteIp = details.getRemoteAddress();
                  logger.info("ip為{}-通過用戶{}調(diào)用接口",remoteIp,username);
                  if(!ips.contains(remoteIp)){
                      throw new DisabledException("無權登陸!");
                  }
            }else{
                throw new DisabledException("賬戶不存在!");
            }
            user.setA("A");
            Collection<GrantedAuthority> authorities = new ArrayList<>();
            return new UsernamePasswordAuthenticationToken(currentUser, credential, authorities);
        } catch (Exception ex) {
            ex.printStackTrace();
            throw new DisabledException("登錄發(fā)生錯誤 : " + ex.getMessage());
        }
    }
    @Override
    public boolean supports(Class<?> arg0) {
        return true;
    }
}

4、主服務feign配置

FeignManage.java

#url = "${file.client.url}",
@FeignClient(name="file-service",
            fallback = FeignFileManageFallback.class,
            configuration = FeignConfiguration.class)
public interface FeignFileManage {
    @RequestMapping(value = "/file/upload", method = {RequestMethod.POST}, consumes = MediaType.MULTIPART_FORM_DATA_VALUE)
    ApiBaseMessage fileUpload(@RequestPart("file") MultipartFile file, @RequestParam("fileName") String fileName) ;
}
public class FeignManageFallback implements FeignManage{
    @Override
    public ApiBaseMessage fileUpload(MultipartFile file, String type) {
        return ApiBaseMessage.getOperationSucceedInstance("400","失敗");
    }
}

FeignFileManageFallback.java

FeignConfiguration.java

@Configuration
@Import(FeignClientsConfiguration.class)
public class FeignConfiguration {
    /**
      刪除請求頭文件
     */
    final String[] copyHeaders = new String[]{"transfer-encoding","Content-Length"};
    @Bean
    public FeignFileManageFallback echoServiceFallback(){
        return new FeignFileManageFallback();
    }
    @Bean
    public FeignBasicAuthRequestInterceptor getFeignBasicAuthRequestInterceptor(){
        return new FeignBasicAuthRequestInterceptor();
    }
    /**
     *    feign 調(diào)用,添加CurrentUser
     */
    private class FeignBasicAuthRequestInterceptor implements RequestInterceptor {
        @Override
        public void apply(RequestTemplate template) {
            //1、使用RequestContextHolder拿到剛進來的請求數(shù)據(jù)
            ServletRequestAttributes requestAttributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
            if (requestAttributes != null) {
                HttpServletRequest request = requestAttributes.getRequest();
                Enumeration<String> headerNames = request.getHeaderNames();
                if (headerNames != null) {
                    while (headerNames.hasMoreElements()) {
                        String name = headerNames.nextElement();
                        String values = request.getHeader(name);
                        //刪除的請求頭
                        if (!Arrays.asList(copyHeaders).contains(name)) {
                            template.header(name, values);
                        }
                    }
                }
            }else{
                template.header("Accept", "*/*");
                template.header("Accept-Encoding", "gzip, deflate, br");
                template.header("Content-Type", "application/json");
            }
            //增加用戶信息
            if(requestAttributes!=null && SessionHelper.getCurrentUser()!=null){
                try {
                    template.header("TaobaoUser", URLEncoder.encode(JSON.toJSONString(SessionHelper.getCurrentUser()),"utf-8") );
                } catch (UnsupportedEncodingException e) {
                    e.printStackTrace();
                }
            }
        }
    }
}

5、主服務session文件

SessionUtil.java

 
public class SessionUtil {
    public static CurrentUser getCurrentUser() {
        HttpSession session = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest().getSession();
        CurrentUser user = (CurrentUser)session.getAttribute("TaobaoUser");
        return user;
    }
    public static void setCurrentUser(String userName){
        HttpSession session = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest().getSession();
        Collection<GrantedAuthority> authorities = new ArrayList<>();
        session.setAttribute("TaobaoUser",new CurrentUser(userName, "", authorities));
    }
}

三、完成配置后

1、直接訪問主服務接口,不登錄無法訪問

2、直接訪問自服務,不登錄無法訪問,(可通過nacos配置用戶密碼實現(xiàn)登錄)

3、主服務通過feign調(diào)用子服務接口正常(session已共享)

4、子服務登陸之后,調(diào)用主服務理論也可以,需校驗下主服務用戶側(cè)

到此這篇關于微服務Redis-Session共享登錄狀態(tài)的文章就介紹到這了,更多相關Redis Session共享登錄狀態(tài)內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!

相關文章

  • mybatis取別名typeAliases標簽的位置放錯導致報錯的解決

    mybatis取別名typeAliases標簽的位置放錯導致報錯的解決

    這篇文章主要介紹了mybatis取別名typeAliases標簽的位置放錯導致報錯的解決方案,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2021-09-09
  • JAVA 運算符歸納總結(jié)

    JAVA 運算符歸納總結(jié)

    這篇文章主要對Java語法基礎之運算符進行了詳細的歸納總結(jié),需要的朋友可以參考
    2017-04-04
  • Spring中基于XML的AOP配置詳解

    Spring中基于XML的AOP配置詳解

    這篇文章主要介紹了Spring中基于XML的AOP配置,本文通過圖文實例相結(jié)合給大家介紹的非常詳細,對大家的學習或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2020-10-10
  • SSM框架+Plupload實現(xiàn)分塊上傳大文件示例

    SSM框架+Plupload實現(xiàn)分塊上傳大文件示例

    這篇文章主要介紹了SSM框架+Plupload實現(xiàn)分塊上傳示例(Spring+SpringMVC+MyBatis+Plupload),將用戶選中的文件(可多個)分隔成一個個小塊,依次向服務器上傳,有興趣的可以了解一下。
    2017-03-03
  • MyBatis?Generator?ORM層面的代碼自動生成器(推薦)

    MyBatis?Generator?ORM層面的代碼自動生成器(推薦)

    Mybatis?Generator是一個專門為?MyBatis和?ibatis框架使用者提供的代碼生成器,也可以快速的根據(jù)數(shù)據(jù)表生成對應的pojo類、Mapper接口、Mapper文件,甚至生成QBC風格的查詢對象,這篇文章主要介紹了MyBatis?Generator?ORM層面的代碼自動生成器,需要的朋友可以參考下
    2023-01-01
  • 向Spring IOC 容器動態(tài)注冊bean實現(xiàn)方式

    向Spring IOC 容器動態(tài)注冊bean實現(xiàn)方式

    這篇文章主要為大家介紹了向Spring IOC 容器動態(tài)注冊bean實現(xiàn)方式詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪
    2022-07-07
  • SparkSQL讀取hive數(shù)據(jù)本地idea運行的方法詳解

    SparkSQL讀取hive數(shù)據(jù)本地idea運行的方法詳解

    這篇文章主要介紹了SparkSQL讀取hive數(shù)據(jù)本地idea運行的方法,本文給大家介紹的非常詳細,對大家的學習或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2020-09-09
  • Struts2源碼分析之ParametersInterceptor攔截器

    Struts2源碼分析之ParametersInterceptor攔截器

    這篇文章主要介紹了Struts2源碼分析之ParametersInterceptor攔截器,ParametersInterceptor攔截器其主要功能是把ActionContext中的請求參數(shù)設置到ValueStack中,,需要的朋友可以參考下
    2019-06-06
  • Java開源工具iText生成PDF簡單實例

    Java開源工具iText生成PDF簡單實例

    這篇文章主要介紹了Java開源工具iText生成PDF簡單實例,本文給出了3段代碼實例,講解創(chuàng)建一個簡單PDF文件,在PDF中添加表格以及在PDF中添加圖片,需要的朋友可以參考下
    2015-07-07
  • spring使用Filter過濾器對Response返回值進行修改的方法

    spring使用Filter過濾器對Response返回值進行修改的方法

    這篇文章主要介紹了spring使用Filter過濾器對Response返回值進行修改,本文通過實例代碼給大家介紹的非常詳細,對大家的學習或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2023-09-09

最新評論