国产 无码 综合区,色欲AV无码国产永久播放,无码天堂亚洲国产AV,国产日韩欧美女同一区二区

SpringCloud gateway+Spring Security + JWT實(shí)現(xiàn)登錄和用戶權(quán)限校驗(yàn)

這篇具有很好參考價(jià)值的文章主要介紹了SpringCloud gateway+Spring Security + JWT實(shí)現(xiàn)登錄和用戶權(quán)限校驗(yàn)。希望對(duì)大家有所幫助。如果存在錯(cuò)誤或未考慮完全的地方,請(qǐng)大家不吝賜教,您也可以點(diǎn)擊"舉報(bào)違法"按鈕提交疑問(wèn)。

引言

原本打算將Security模塊與gateway模塊分開(kāi)寫(xiě)的,但想到gateway本來(lái)就有過(guò)濾的作用 ,于是就把gateway和Security結(jié)合在一起了,然后結(jié)合JWT令牌對(duì)用戶身份和權(quán)限進(jìn)行校驗(yàn)。

Spring Cloud的網(wǎng)關(guān)與傳統(tǒng)的SpringMVC不同,gateway是基于Netty容器,采用的webflux技術(shù),所以gateway模塊不能引入spring web包。雖然是不同,但是在SpringMVC模式下的Security實(shí)現(xiàn)步驟和流程都差不多。

依賴

Spring? cloud gateway模塊依賴

<dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-gateway</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
        </dependency>

        <!--JWT的依賴-->
        <dependency>
            <groupId>com.auth0</groupId>
            <artifactId>java-jwt</artifactId>
            <version>3.4.0</version>
        </dependency>
        <dependency>
            <groupId>com.fasterxml.jackson.datatype</groupId>
            <artifactId>jackson-datatype-jsr310</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-redis</artifactId>
        </dependency>
        <dependency>
            <groupId>redis.clients</groupId>
            <artifactId>jedis</artifactId>
            <type>jar</type>
        </dependency>
        <dependency>
            <groupId>org.springframework.data</groupId>
            <artifactId>spring-data-redis</artifactId>
        </dependency>

代碼基本結(jié)構(gòu)

springcloudgateway權(quán)限驗(yàn)證,spring,spring cloud,gateway,后端,java-ee

認(rèn)證執(zhí)行流程

一、Token工具類

public class JWTUtils {
    private final static String SING="XIAOYUAN";
    public static String creatToken(Map<String,String> payload,int expireTime){
        JWTCreator.Builder builder= JWT.create();
        Calendar instance=Calendar.getInstance();//獲取日歷對(duì)象
        if(expireTime <=0)
        instance.add(Calendar.SECOND,3600);//默認(rèn)一小時(shí)
        else
            instance.add(Calendar.SECOND,expireTime);
        //為了方便只放入了一種類型
        payload.forEach(builder::withClaim);
        return builder.withExpiresAt(instance.getTime()).sign(Algorithm.HMAC256(SING));
    }
    public static Map<String, Object> getTokenInfo(String token){
        DecodedJWT verify = JWT.require(Algorithm.HMAC256(SING)).build().verify(token);
        Map<String, Claim> claims = verify.getClaims();
        SimpleDateFormat dateTime = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        String expired= dateTime.format(verify.getExpiresAt());
        Map<String,Object> m=new HashMap<>();
        claims.forEach((k,v)-> m.put(k,v.asString()));
        m.put("exp",expired);
        return m;

    }
}

二、自定義User并且實(shí)現(xiàn)Spring Security的User接口,以及實(shí)現(xiàn)UserDetail接口

 
public class SecurityUserDetails extends User implements Serializable {

    private Long userId;

    public SecurityUserDetails(String username, String password, Collection<? extends GrantedAuthority> authorities, Long userId) {
        super(username, password, authorities);
        this.userId = userId;
    }

    public SecurityUserDetails(String username, String password, boolean enabled, boolean accountNonExpired, boolean credentialsNonExpired, boolean accountNonLocked, Collection<? extends GrantedAuthority> authorities, Long userId) {
        super(username, password, enabled, accountNonExpired, credentialsNonExpired, accountNonLocked, authorities);
        this.userId = userId;
    }

    public Long getUserId() {
        return userId;
    }

    public void setUserId(Long userId) {
        this.userId = userId;
    }
}

@Component("securityUserDetailsService")
@Slf4j
public class SecurityUserDetailsService implements ReactiveUserDetailsService {
    private final PasswordEncoder passwordEncoder= new BCryptPasswordEncoder();;
    @Override
    public Mono<UserDetails> findByUsername(String username) {
        //調(diào)用數(shù)據(jù)庫(kù)根據(jù)用戶名獲取用戶
        log.info(username);
        if(!username.equals("admin")&&!username.equals("user"))
                throw new UsernameNotFoundException("username error");
        else {
            Collection<GrantedAuthority> authorities = new ArrayList<>();
            if (username.equals("admin"))
            authorities.add(new SimpleGrantedAuthority("ROLE_ADMIN"));//ROLE_ADMIN
            if (username.equals("user"))
                authorities.add(new SimpleGrantedAuthority("ROLE_USER"));//ROLE_ADMIN
            SecurityUserDetails securityUserDetails = new SecurityUserDetails(username,"{bcrypt}"+passwordEncoder.encode("123"),authorities,1L);
            return Mono.just(securityUserDetails);
        }

    }
}

這里我為了方便測(cè)試,只設(shè)置了兩個(gè)用戶,admin和晢user,用戶角色也只有一種。

二、AuthenticationSuccessHandler,定義認(rèn)證成功類

@Component
@Slf4j
public class AuthenticationSuccessHandler extends WebFilterChainServerAuthenticationSuccessHandler {
    @Value("${login.timeout}")
    private int timeout=3600;//默認(rèn)一小時(shí)
    private final int rememberMe=180;
    @Autowired
    private RedisTemplate<String, Object> redisTemplate;

    @SneakyThrows
    @Override
    public Mono<Void> onAuthenticationSuccess(WebFilterExchange webFilterExchange, Authentication authentication) {
        ServerWebExchange exchange = webFilterExchange.getExchange();
        ServerHttpResponse response = exchange.getResponse();
        //設(shè)置headers
        HttpHeaders httpHeaders = response.getHeaders();
        httpHeaders.add("Content-Type", "application/json; charset=UTF-8");
        httpHeaders.add("Cache-Control", "no-store, no-cache, must-revalidate, max-age=0");
        //設(shè)置body
        HashMap<String, String> map = new HashMap<>();
        String remember_me=exchange.getRequest().getHeaders().getFirst("Remember-me");

        ObjectMapper mapper = new ObjectMapper();
        List<? extends GrantedAuthority> list=authentication.getAuthorities().stream().toList();
          try {
            Map<String, String> load = new HashMap<>();
            load.put("username",authentication.getName());
            load.put("role",list.get(0).getAuthority());//這里只添加了一種角色 實(shí)際上用戶可以有不同的角色類型
            String token;
            log.info(authentication.toString());
            if (remember_me==null) {
                token=JWTUtils.creatToken(load,3600*24);
                response.addCookie(ResponseCookie.from("token", token).path("/").build());
                //maxAge默認(rèn)-1 瀏覽器關(guān)閉cookie失效
                redisTemplate.opsForValue().set(authentication.getName(), token, 1, TimeUnit.DAYS);
            }else {
                token=JWTUtils.creatToken(load,3600*24*180);
                response.addCookie(ResponseCookie.from("token", token).maxAge(Duration.ofDays(rememberMe)).path("/").build());
                redisTemplate.opsForValue().set(authentication.getName(), token, rememberMe, TimeUnit.SECONDS);//保存180天
            }

            map.put("code", "000220");
            map.put("message", "登錄成功");
            map.put("token",token);
        } catch (Exception ex) {
            ex.printStackTrace();
              map.put("code", "000440");
            map.put("message","登錄失敗");
        }
        DataBuffer bodyDataBuffer = response.bufferFactory().wrap(mapper.writeValueAsBytes(map));
        return response.writeWith(Mono.just(bodyDataBuffer));
    }
    
}

當(dāng)用戶認(rèn)證成功的時(shí)候就會(huì)調(diào)用這個(gè)類,這里我將token作為cookie返回客戶端,當(dāng)客服端請(qǐng)求接口的時(shí)候?qū)螩ookie,然后gateway在認(rèn)證之前攔截,然后將Cookie寫(xiě)入Http請(qǐng)求頭中,后面的授權(quán)在請(qǐng)求頭中獲取token。(這里我使用的cookie來(lái)保存token,當(dāng)然也可以保存在localStorage里,每次請(qǐng)求的headers里面帶上token)

這里還實(shí)現(xiàn)了一個(gè)記住用戶登錄的功能,原本是打算讀取請(qǐng)求頭中的表單數(shù)據(jù)的Remember-me字段來(lái)判斷是否記住用戶登錄狀態(tài),但是這里有一個(gè)問(wèn)題,在獲取請(qǐng)求的表單數(shù)據(jù)的時(shí)候一直為空,因?yàn)閃ebflux中請(qǐng)求體中的數(shù)據(jù)只能被讀取一次,如果讀取了就需要重新封裝,前面在進(jìn)行用戶認(rèn)證的時(shí)候已經(jīng)讀取過(guò)了請(qǐng)求體導(dǎo)致后面就讀取不了(只是猜測(cè),因?yàn)閯倢W(xué)習(xí)gateway還不是很了解,在網(wǎng)上查了很多資料一直沒(méi)有解決這個(gè)問(wèn)題),于是我用了另一個(gè)方法,需要記住用戶登錄狀態(tài)的時(shí)候(Remember-me),我就在前端請(qǐng)求的時(shí)候往Http請(qǐng)求頭加一個(gè)Remember-me字段,然后后端判斷有沒(méi)有這個(gè)字段,沒(méi)有的話就不記住。

三、AuthenticationFaillHandler? ,認(rèn)證失敗類

@Slf4j
@Component
public class AuthenticationFaillHandler  implements ServerAuthenticationFailureHandler {

    @SneakyThrows
    @Override
    public Mono<Void> onAuthenticationFailure(WebFilterExchange webFilterExchange, AuthenticationException e) {
        ServerHttpResponse response = webFilterExchange.getExchange().getResponse();
        response.setStatusCode(HttpStatus.FORBIDDEN);
        response.getHeaders().add("Content-Type", "application/json; charset=UTF-8");
        HashMap<String, String> map = new HashMap<>();
        map.put("code", "000400");
        map.put("message", e.getMessage());
        log.error("access forbidden path={}", webFilterExchange.getExchange().getRequest().getPath());
        ObjectMapper objectMapper = new ObjectMapper();
        DataBuffer dataBuffer = response.bufferFactory().wrap(objectMapper.writeValueAsBytes(map));
        return response.writeWith(Mono.just(dataBuffer));
    }
}

四、SecurityRepository ,用戶信息上下文存儲(chǔ)類

@Slf4j
@Component
public class SecurityRepository implements ServerSecurityContextRepository {
    @Autowired
    private RedisTemplate<String, Object> redisTemplate;

    @Override
    public Mono<Void> save(ServerWebExchange exchange, SecurityContext context) {
        return Mono.empty();
    }

    @Override
    public Mono<SecurityContext> load(ServerWebExchange exchange) {
        String token = exchange.getRequest().getHeaders().getFirst(HttpHeaders.AUTHORIZATION);
        log.info(token);
        if (token != null) {
            try {
                Map<String,Object> userMap= JWTUtils.getTokenInfo(token);
                String result=(String)redisTemplate.opsForValue().get(userMap.get("username"));
                if (result==null || !result.equals(token))
                    return Mono.empty();
                SecurityContext emptyContext = SecurityContextHolder.createEmptyContext();
                Collection<SimpleGrantedAuthority> authorities=new ArrayList<>();
                log.info((String) userMap.get("role"));
                authorities.add(new SimpleGrantedAuthority((String) userMap.get("role")));
                Authentication authentication=new UsernamePasswordAuthenticationToken(null, null,authorities);
                emptyContext.setAuthentication(authentication);
                return Mono.just(emptyContext);
            }catch (Exception e) {
                return Mono.empty();
            }
        }
        return Mono.empty();
    }
}

當(dāng)客戶端訪問(wèn)服務(wù)接口的時(shí)候,如果是有效token,那么就根據(jù)token來(lái)判斷用戶權(quán)限,實(shí)現(xiàn)ServerSecurityContextRepository?類的主要目的是實(shí)現(xiàn)load方法,這個(gè)方法實(shí)際上是傳遞一個(gè)Authentication對(duì)象供后面ReactiveAuthorizationManager<AuthorizationContext>來(lái)判斷用戶權(quán)限。我這里只傳遞了用戶的role信息,所以就沒(méi)有去實(shí)現(xiàn)ReactiveAuthorizationManager這個(gè)接口了。

Security框架默認(rèn)提供了兩個(gè)ServerSecurityContextRepository實(shí)現(xiàn)類,WebSessionServerSecurityContextRepository和NoOpServerSecurityContextRepository,Security默認(rèn)使用WebSessionServerSecurityContextRepository,這個(gè)是使用session來(lái)保存用戶登錄狀態(tài)的,NoOpServerSecurityContextRepository是無(wú)狀態(tài)的。

五、AuthenticationEntryPoint ,接口認(rèn)證入口類

如果客戶端沒(méi)有認(rèn)證授權(quán)就直接訪問(wèn)服務(wù)接口,然后就會(huì)調(diào)用這個(gè)類,返回的狀態(tài)碼是401


@Slf4j
@Component
public class AuthenticationEntryPoint extends HttpBasicServerAuthenticationEntryPoint {
    @SneakyThrows
    @Override
    public Mono<Void> commence(ServerWebExchange exchange, AuthenticationException e) {
        ServerHttpResponse response = exchange.getResponse();
        response.setStatusCode(HttpStatus.UNAUTHORIZED);
        response.getHeaders().add("Content-Type", "application/json; charset=UTF-8");
        HashMap<String, String> map = new HashMap<>();
        map.put("status", "00401");
        map.put("message", "未登錄");
        ObjectMapper objectMapper = new ObjectMapper();
        DataBuffer bodyDataBuffer = response.bufferFactory().wrap(objectMapper.writeValueAsBytes(map));
        return response.writeWith(Mono.just(bodyDataBuffer));
    }
}

六、AccessDeniedHandler ,授權(quán)失敗處理類

當(dāng)訪問(wèn)服務(wù)接口的用戶權(quán)限不夠時(shí)會(huì)調(diào)用這個(gè)類,返回HTTP狀態(tài)碼是403

@Slf4j
@Component
public class AccessDeniedHandler implements ServerAccessDeniedHandler {
    @SneakyThrows
    @Override
    public Mono<Void> handle(ServerWebExchange exchange, AccessDeniedException denied) {
        ServerHttpResponse response = exchange.getResponse();
        response.setStatusCode(HttpStatus.FORBIDDEN);
        response.getHeaders().add("Content-Type", "application/json; charset=UTF-8");
        HashMap<String, String> map = new HashMap<>();
        map.put("code", "000403");
        map.put("message", "未授權(quán)禁止訪問(wèn)");
        log.error("access forbidden path={}", exchange.getRequest().getPath());
        ObjectMapper objectMapper = new ObjectMapper();
        DataBuffer dataBuffer = response.bufferFactory().wrap(objectMapper.writeValueAsBytes(map));
        return response.writeWith(Mono.just(dataBuffer));
    }
}

七、AuthorizationManager ,鑒權(quán)管理類

@Slf4j
@Component
public class AuthorizationManager implements ReactiveAuthorizationManager<AuthorizationContext> {
    @Override
    public Mono<AuthorizationDecision> check(Mono<Authentication> authentication, AuthorizationContext authorizationContext) {
        return authentication.map(auth -> {
            //SecurityUserDetails userSecurity = (SecurityUserDetails) auth.getPrincipal();
            String path=authorizationContext.getExchange().getRequest().getURI().getPath();
            for (GrantedAuthority authority : auth.getAuthorities()){
                if (authority.getAuthority().equals("ROLE_USER")&&path.contains("/user/normal"))
                    return new AuthorizationDecision(true);
                else if (authority.getAuthority().equals("ROLE_ADMIN")&&path.contains("/user/admin"))
                    return new AuthorizationDecision(true);
//對(duì)客戶端訪問(wèn)路徑與用戶角色進(jìn)行匹配
            }
            return new AuthorizationDecision(false);
        }).defaultIfEmpty(new AuthorizationDecision(false));
    }
}

返回new AuthorizationDecision(true)代表授予權(quán)限訪問(wèn)服務(wù),為false則是拒絕。

八、LogoutHandler,LogoutSuccessHandler?登出處理類

@Component
@Slf4j
public class LogoutHandler implements ServerLogoutHandler {
    @Autowired
    private RedisTemplate<String,Object> redisTemplate;
    @Override
    public Mono<Void> logout(WebFilterExchange webFilterExchange, Authentication authentication) {
        HttpCookie cookie=webFilterExchange.getExchange().getRequest().getCookies().getFirst("token");
        try {
            if (cookie != null) {
                Map<String,Object> userMap= JWTUtils.getTokenInfo(cookie.getValue());
                redisTemplate.delete((String) userMap.get("username"));
            }
        }catch (JWTDecodeException e) {
           return Mono.error(e);
        }

        return Mono.empty();
    }
}
@Component
public class LogoutSuccessHandler implements ServerLogoutSuccessHandler {
    @SneakyThrows
    @Override
    public Mono<Void> onLogoutSuccess(WebFilterExchange webFilterExchange, Authentication authentication) {
        ServerHttpResponse response = webFilterExchange.getExchange().getResponse();
        //設(shè)置headers
        HttpHeaders httpHeaders = response.getHeaders();
        httpHeaders.add("Content-Type", "application/json; charset=UTF-8");
        httpHeaders.add("Cache-Control", "no-store, no-cache, must-revalidate, max-age=0");
        //設(shè)置body
        HashMap<String, String> map = new HashMap<>();
        //刪除token
        response.addCookie(ResponseCookie.from("token", "logout").maxAge(0).path("/").build());
        map.put("code", "000220");
        map.put("message", "退出登錄成功");
        ObjectMapper mapper = new ObjectMapper();
        DataBuffer bodyDataBuffer = response.bufferFactory().wrap(mapper.writeValueAsBytes(map));
        return response.writeWith(Mono.just(bodyDataBuffer));
    }
}

九、CookieToHeadersFilter ,將Cookie寫(xiě)入Http請(qǐng)求頭中

@Slf4j
@Component
public class CookieToHeadersFilter implements WebFilter{
    @Override
    public Mono<Void> filter(ServerWebExchange exchange, WebFilterChain chain) {
        try {

            HttpCookie cookie=exchange.getRequest().getCookies().getFirst("token");
            if (cookie != null) {
                String token = cookie.getValue();
                ServerHttpRequest request=exchange.getRequest().mutate().header(HttpHeaders.AUTHORIZATION,token).build();
                return chain.filter(exchange.mutate().request(request).build());
            }
        }catch (NoFoundToken e) {
            log.error(e.getMsg());
        }

        return chain.filter(exchange);

    }

}

這里需要注意的是,如果要想在認(rèn)證前后過(guò)濾Http請(qǐng)求,用全局過(guò)濾器或者局部過(guò)濾器是不起作用的,因?yàn)樗鼈兛偸窃阼b權(quán)通過(guò)后執(zhí)行,也就是它們的執(zhí)行順序始終再Security過(guò)濾器之后,無(wú)論order值多大多小。這時(shí)候必須實(shí)現(xiàn)的接口是WebFilter而不是GlobalFilter或者GatewayFilter,然后將接口實(shí)現(xiàn)類添加到WebSecurityConfig配置中心去。

十、WebSecurityConfig,配置類

@EnableWebFluxSecurity
@Configuration
@Slf4j
public class WebSecurityConfig {
    @Autowired
    SecurityUserDetailsService securityUserDetailsService;
    @Autowired
    AuthorizationManager authorizationManager;
    @Autowired
    AccessDeniedHandler accessDeniedHandler;
    @Autowired
    AuthenticationSuccessHandler authenticationSuccessHandler;
    @Autowired
    AuthenticationFaillHandler authenticationFaillHandler;
    @Autowired
    SecurityRepository securityRepository;
    @Autowired
    CookieToHeadersFilter cookieToHeadersFilter;
    @Autowired
    LogoutSuccessHandler logoutSuccessHandler;
    @Autowired
    LogoutHandler logoutHandler;

    @Autowired
    com.example.gateway.security.AuthenticationEntryPoint authenticationEntryPoint;
    private final String[] path={
            "/favicon.ico",
            "/book/**",
            "/user/login.html",
            "/user/__MACOSX/**",
            "/user/css/**",
            "/user/fonts/**",
            "/user/images/**"};
    @Bean
    public SecurityWebFilterChain springSecurityFilterChain(ServerHttpSecurity http) {
        http.addFilterBefore(cookieToHeadersFilter, SecurityWebFiltersOrder.HTTP_HEADERS_WRITER);
        //SecurityWebFiltersOrder枚舉類定義了執(zhí)行次序
        http.authorizeExchange(exchange -> exchange // 請(qǐng)求攔截處理
                                .pathMatchers(path).permitAll()
                                .pathMatchers(HttpMethod.OPTIONS).permitAll()
                                .anyExchange().access(authorizationManager)//權(quán)限
                        //.and().authorizeExchange().pathMatchers("/user/normal/**").hasRole("ROLE_USER")
                        //.and().authorizeExchange().pathMatchers("/user/admin/**").hasRole("ROLE_ADMIN")
                        //也可以這樣寫(xiě) 將匹配路徑和角色權(quán)限寫(xiě)在一起
                )
                .httpBasic()
                .and()
                .formLogin().loginPage("/user/login")//登錄接口
                .authenticationSuccessHandler(authenticationSuccessHandler) //認(rèn)證成功
                .authenticationFailureHandler(authenticationFaillHandler) //登陸驗(yàn)證失敗
                .and().exceptionHandling().authenticationEntryPoint(authenticationEntryPoint)
                .accessDeniedHandler(accessDeniedHandler)//基于http的接口請(qǐng)求鑒權(quán)失敗
                .and().csrf().disable()//必須支持跨域
                .logout().logoutUrl("/user/logout")
                .logoutHandler(logoutHandler)
                .logoutSuccessHandler(logoutSuccessHandler);
        http.securityContextRepository(securityRepository);
        //http.securityContextRepository(NoOpServerSecurityContextRepository.getInstance());//無(wú)狀態(tài) 默認(rèn)情況下使用的WebSession
        return http.build();
    }

    @Bean
    public ReactiveAuthenticationManager reactiveAuthenticationManager() {
        LinkedList<ReactiveAuthenticationManager> managers = new LinkedList<>();
        managers.add(authentication -> {
            // 其他登陸方式
            return Mono.empty();
        });
        managers.add(new UserDetailsRepositoryReactiveAuthenticationManager(securityUserDetailsService));
        return new DelegatingReactiveAuthenticationManager(managers);
    }

}




十一、測(cè)試

首先沒(méi)有登錄訪問(wèn)服務(wù)

springcloudgateway權(quán)限驗(yàn)證,spring,spring cloud,gateway,后端,java-ee

然后登錄?

springcloudgateway權(quán)限驗(yàn)證,spring,spring cloud,gateway,后端,java-ee

訪問(wèn)服務(wù)

springcloudgateway權(quán)限驗(yàn)證,spring,spring cloud,gateway,后端,java-ee

訪問(wèn)另一個(gè)接口

springcloudgateway權(quán)限驗(yàn)證,spring,spring cloud,gateway,后端,java-ee文章來(lái)源地址http://www.zghlxwxcb.cn/news/detail-779929.html

到了這里,關(guān)于SpringCloud gateway+Spring Security + JWT實(shí)現(xiàn)登錄和用戶權(quán)限校驗(yàn)的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!

本文來(lái)自互聯(lián)網(wǎng)用戶投稿,該文觀點(diǎn)僅代表作者本人,不代表本站立場(chǎng)。本站僅提供信息存儲(chǔ)空間服務(wù),不擁有所有權(quán),不承擔(dān)相關(guān)法律責(zé)任。如若轉(zhuǎn)載,請(qǐng)注明出處: 如若內(nèi)容造成侵權(quán)/違法違規(guī)/事實(shí)不符,請(qǐng)點(diǎn)擊違法舉報(bào)進(jìn)行投訴反饋,一經(jīng)查實(shí),立即刪除!

領(lǐng)支付寶紅包贊助服務(wù)器費(fèi)用

相關(guān)文章

  • Java開(kāi)發(fā) - 單點(diǎn)登錄初體驗(yàn)(Spring Security + JWT)

    Java開(kāi)發(fā) - 單點(diǎn)登錄初體驗(yàn)(Spring Security + JWT)

    目錄 ??????? 前言 為什么要登錄 登錄的種類 Cookie-Session Cookie-Session-local storage JWT令牌 幾種登陸總結(jié)? 用戶身份認(rèn)證與授權(quán) 創(chuàng)建工程 添加依賴 啟動(dòng)項(xiàng)目 Bcrypt算法的工具 創(chuàng)建VO模型類 創(chuàng)建接口文件 創(chuàng)建XML文件 補(bǔ)充配置 添加依賴 添加配置 創(chuàng)建配置類 測(cè)試上面的配置

    2024年02月02日
    瀏覽(22)
  • spring boot中常用的安全框架 Security框架 利用Security框架實(shí)現(xiàn)用戶登錄驗(yàn)證token和用戶授權(quán)(接口權(quán)限控制)

    spring boot中常用的安全框架 Security框架 利用Security框架實(shí)現(xiàn)用戶登錄驗(yàn)證token和用戶授權(quán)(接口權(quán)限控制)

    spring boot中常用的安全框架 Security 和 Shiro 框架 Security 兩大核心功能 認(rèn)證 和 授權(quán) 重量級(jí) Shiro 輕量級(jí)框架 不限于web 開(kāi)發(fā) 在不使用安全框架的時(shí)候 一般我們利用過(guò)濾器和 aop自己實(shí)現(xiàn) 權(quán)限驗(yàn)證 用戶登錄 Security 實(shí)現(xiàn)邏輯 輸入用戶名和密碼 提交 把提交用戶名和密碼封裝對(duì)象

    2024年02月06日
    瀏覽(31)
  • SpringCloud搭建微服務(wù)之Gateway+Jwt實(shí)現(xiàn)統(tǒng)一鑒權(quán)

    SpringCloud搭建微服務(wù)之Gateway+Jwt實(shí)現(xiàn)統(tǒng)一鑒權(quán)

    在微服務(wù)項(xiàng)目中,需要對(duì)整個(gè)微服務(wù)系統(tǒng)進(jìn)行權(quán)限校驗(yàn),通常有兩種方案,其一是每個(gè)微服務(wù)各自鑒權(quán),其二是在網(wǎng)關(guān)統(tǒng)一鑒權(quán),第二種方案只需要一次鑒權(quán)就行,避免了每個(gè)微服務(wù)重復(fù)鑒權(quán)的麻煩,本文以網(wǎng)關(guān)統(tǒng)一鑒權(quán)為例介紹如何搭建微服務(wù)鑒權(quán)項(xiàng)目。 本文案例中共有四

    2024年02月13日
    瀏覽(23)
  • Spring Security登錄用戶數(shù)據(jù)獲?。?)

    Spring Security登錄用戶數(shù)據(jù)獲?。?)

    登錄成功之后,在后續(xù)的業(yè)務(wù)邏輯中,開(kāi)發(fā)者可能還需要獲取登錄成功的用戶對(duì)象,如果不使用任何安全管理框架,那么可以將用戶信息保存在HttpSession中,以后需要的時(shí)候直接從HttpSession中獲取數(shù)據(jù)。在Spring Security中,用戶登錄信息本質(zhì)上還是保存在 HttpSession中,但是為了方

    2024年02月03日
    瀏覽(17)
  • Spring Gateway使用JWT實(shí)現(xiàn)統(tǒng)一身份認(rèn)證

    Spring Gateway使用JWT實(shí)現(xiàn)統(tǒng)一身份認(rèn)證

    在開(kāi)發(fā)集群式或分布式服務(wù)時(shí),鑒權(quán)是最重要的一步,為了方便對(duì)請(qǐng)求統(tǒng)一鑒權(quán),一般都是會(huì)放在網(wǎng)關(guān)中進(jìn)行處理。目前非常流行的一種方案是使用JWT,詳細(xì)的使用說(shuō)明,可以找相關(guān)的資料查閱,這里先不進(jìn)行深入的引用了。主要使用它下面的特性: 它的數(shù)據(jù)使用JSON格式封

    2024年02月12日
    瀏覽(18)
  • 【深入淺出 Spring Security(四)】登錄用戶數(shù)據(jù)的獲取,超詳細(xì)的源碼分析

    【深入淺出 Spring Security(四)】登錄用戶數(shù)據(jù)的獲取,超詳細(xì)的源碼分析

    在【深入淺出Spring Security(一)】Spring Security的整體架構(gòu) 中敘述過(guò)一個(gè)SecurityContextHolder 這個(gè)類。說(shuō)在處理請(qǐng)求時(shí),Spring Security 會(huì)先從 Session 中取出用戶登錄數(shù)據(jù),保存到 SecurityContextHolder 中,然后在請(qǐng)求處理完畢后,又會(huì)拿 SecurityContextHolder 中的數(shù)據(jù)保存到 Session 中,然后再

    2024年02月07日
    瀏覽(18)
  • 基于SpringCloud + Oauth2.0 + ShiroRedis + JWT + Gateway + Nacos + Nginx + Vue實(shí)現(xiàn)的SaaS數(shù)字商城系統(tǒng)

    基于SpringCloud + Oauth2.0 + ShiroRedis + JWT + Gateway + Nacos + Nginx + Vue實(shí)現(xiàn)的SaaS數(shù)字商城系統(tǒng)

    SaaS的英文全稱是Software as a Service,意思是軟件即服務(wù) ,是云計(jì)算的其中一種服務(wù)模式 SaaS是一種通過(guò)Internet提供集中托管應(yīng)用程序的方式,企業(yè)用戶一般通過(guò)客戶端或網(wǎng)頁(yè)來(lái)使用,無(wú)需購(gòu)買、安裝或維護(hù)任何軟件及硬件,因此 SaaS應(yīng)用程序又被稱為\\\"基于Web的軟件\\\" 或 \\\"托管軟件

    2024年01月20日
    瀏覽(24)
  • Spring Gateway+Security+OAuth2+RBAC 實(shí)現(xiàn)SSO統(tǒng)一認(rèn)證平臺(tái)

    Spring Gateway+Security+OAuth2+RBAC 實(shí)現(xiàn)SSO統(tǒng)一認(rèn)證平臺(tái)

    背景:新項(xiàng)目準(zhǔn)備用SSO來(lái)整合之前多個(gè)項(xiàng)目的登錄和權(quán)限,同時(shí)引入網(wǎng)關(guān)來(lái)做后續(xù)的服務(wù)限流之類的操作,所以搭建了下面這個(gè)系統(tǒng)雛形。 : Spring Gateway, Spring Security, JWT, OAuth2, Nacos, Redis, Danymic datasource, Javax,?thymeleaf 如果對(duì)上面這些技術(shù)感興趣,可以繼續(xù)往下閱讀 如

    2024年02月13日
    瀏覽(25)
  • SpringCloud整合spring security+ oauth2+Redis實(shí)現(xiàn)認(rèn)證授權(quán)

    SpringCloud整合spring security+ oauth2+Redis實(shí)現(xiàn)認(rèn)證授權(quán)

    在微服務(wù)構(gòu)建中,我們一般用一個(gè)父工程來(lái)通知管理依賴的各種版本號(hào)信息。父工程pom文件如下: 在SpringCloud微服務(wù)體系中服務(wù)注冊(cè)中心是一個(gè)必要的存在,通過(guò)注冊(cè)中心提供服務(wù)的注冊(cè)和發(fā)現(xiàn)。具體細(xì)節(jié)可以查看我之前的博客,這里不再贅述。我們開(kāi)始構(gòu)建一個(gè)eureka注冊(cè)中

    2024年02月06日
    瀏覽(25)
  • Spring-Security實(shí)現(xiàn)登錄接口

    Spring-Security實(shí)現(xiàn)登錄接口

    Security 是 Spring 家族中的一個(gè)安全管理框架。相比與另外一個(gè)安全框架 Shiro ,它提供了更豐富的功能,社區(qū)資源也比Shiro豐富。 具體介紹和入門看springSecurity入門 在實(shí)現(xiàn)之前幺要了解一下登錄校驗(yàn)的流程以及 SpringSecurity 的原理以及認(rèn)證流程 1、登錄校驗(yàn)流程 2、 SpringSecurity完

    2024年01月18日
    瀏覽(22)

覺(jué)得文章有用就打賞一下文章作者

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

請(qǐng)作者喝杯咖啡吧~博客贊助

支付寶掃一掃領(lǐng)取紅包,優(yōu)惠每天領(lǐng)

二維碼1

領(lǐng)取紅包

二維碼2

領(lǐng)紅包