久久久久久久av_日韩在线中文_看一级毛片视频_日本精品二区_成人深夜福利视频_武道仙尊动漫在线观看

Spring Security MultiHttpSecurity 配置使我可以執行兩種

Spring Security MultiHttpSecurity Configuration so that I can perform two types of authentication. JWT Token and Session Cookie(Spring Security MultiHttpSecurity 配置使我可以執行兩種類型的身份驗證.JWT 令牌和會話 Cookie)
本文介紹了Spring Security MultiHttpSecurity 配置使我可以執行兩種類型的身份驗證.JWT 令牌和會話 Cookie的處理方法,對大家解決問題具有一定的參考價值,需要的朋友們下面隨著小編來一起學習吧!

問題描述

我的應用程序已經有了 Spring Security Cookie 機制,現在只針對 API,我需要添加基于 JWT Token 的身份驗證機制.我正在使用 Spring Security 的 MultiHttpSecurityConfiguration 和兩個嵌套類.

I already have Spring Security Cookie mechanism in place for my application, now only for the API's, I need to add JWT Token-based authentication mechanism. I'm using Spring Security's MultiHttpSecurityConfiguration with two nested class.

會話和 JWT 令牌機制是否應該一起包含在一個應用程序中是完全不同的問題,我需要實現兩件事.

Whether both session and JWT token mechanism should be included together in one application or not is a different question altogether, I need to achieve two things.

  1. Spring Security 的基于會話的 cookie 身份驗證將像以前一樣工作.
  2. 需要為 API 添加一個身份驗證標頭

package com.leadwinner.sms.config;

import java.util.Collections;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.annotation.Order;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.ProviderManager;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.config.http.SessionCreationPolicy;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.security.web.authentication.AuthenticationSuccessHandler;
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;
import org.springframework.security.web.authentication.logout.LogoutSuccessHandler;

import com.leadwinner.sms.CustomAuthenticationSuccessHandler;
import com.leadwinner.sms.CustomLogoutSuccessHandler;
import com.leadwinner.sms.config.jwt.JwtAuthenticationProvider;
import com.leadwinner.sms.config.jwt.JwtAuthenticationTokenFilter;
import com.leadwinner.sms.config.jwt.JwtSuccessHandler;

@EnableWebSecurity
@EnableGlobalMethodSecurity(prePostEnabled = true, securedEnabled = true)
@ComponentScan(basePackages = "com.leadwinner.sms")
public class MultiHttpSecurityConfig {

    @Autowired
    @Qualifier("userServiceImpl")
    private UserDetailsService userServiceImpl;

    @Autowired
    private JwtAuthenticationProvider authenticationProvider;

    @Autowired
    public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
        auth.userDetailsService(userServiceImpl).passwordEncoder(passwordEncoder());
    }

    @Bean
    public PasswordEncoder passwordEncoder() {
        return  new BCryptPasswordEncoder();
    }

    @Bean
    public AuthenticationManager authenticationManager() {
        return new ProviderManager(Collections.singletonList(authenticationProvider));
    }

    @Configuration
    @Order(1)
    public static class JwtSecurityConfig extends WebSecurityConfigurerAdapter {

         @Autowired
         private JwtAuthenticationTokenFilter jwtauthFilter;

        @Override
        public void configure(HttpSecurity http) throws Exception {
        http.csrf().disable()
            .antMatcher("/web/umgmt/**").authorizeRequests()
            .antMatchers("/web/umgmt/**").authenticated()
            .and()
            .addFilterBefore(jwtauthFilter, UsernamePasswordAuthenticationFilter.class);
         http.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS);
        }
    }

    @Configuration
    @Order(2)
    public static class SecurityConfig extends WebSecurityConfigurerAdapter {
        private  final Logger logger = LoggerFactory.getLogger(SecurityConfig.class);

        @Bean
        public CustomAuthenticationEntryPoint getBasicAuthEntryPoint() {
            return new CustomAuthenticationEntryPoint();
        }

        @Override
        public void configure(HttpSecurity http) throws Exception {

            logger.info("http configure");
            http
            .antMatcher("/**").authorizeRequests()          
            .antMatchers("/login/authenticate").permitAll()
                    .antMatchers("/resources/js/**").permitAll()
                    .antMatchers("/resources/css/**").permitAll()
                    .antMatchers("/resources/images/**").permitAll()
                    .antMatchers("/web/initial/setup/**").permitAll()
                    .antMatchers("/dsinput/**").permitAll().antMatchers("/dsoutput/**").permitAll()                 

                    .and()
                .formLogin()
                    .loginPage("/login").usernameParameter("employeeId").passwordParameter("password")
                    .successForwardUrl("/dashboard")
                    .defaultSuccessUrl("/dashboard", true)
                    .successHandler(customAuthenticationSuccessHandler())
                    .failureForwardUrl("/logout")
                    .loginProcessingUrl("/j_spring_security_check")
                    .and().logout()
                    .logoutSuccessUrl("/logout").logoutUrl("/j_spring_security_logout")
                    .logoutSuccessHandler(customLogoutSuccessHandler())
                    .permitAll()
                    .invalidateHttpSession(true)
                    .deleteCookies("JSESSIONID")
                    .and().sessionManagement()
                    .sessionFixation().none()
                    .sessionCreationPolicy(SessionCreationPolicy.ALWAYS)
                    .invalidSessionUrl("/logout")
                    .and().exceptionHandling().accessDeniedPage("/logout").and().csrf().disable();
            http.authorizeRequests().anyRequest().authenticated();


        }

        @Bean
        public AuthenticationSuccessHandler customAuthenticationSuccessHandler() {
            return new CustomAuthenticationSuccessHandler();
        }

        @Bean
        public LogoutSuccessHandler customLogoutSuccessHandler() {
            return new CustomLogoutSuccessHandler();
        }
    }
}

JwtAuthenticationTokenFilter.java

JwtAuthenticationTokenFilter.java

package com.leadwinner.sms.config.jwt;

import java.io.IOException;

import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.web.authentication.WebAuthenticationDetailsSource;
import org.springframework.web.filter.OncePerRequestFilter;

public class JwtAuthenticationTokenFilter extends OncePerRequestFilter {
    @Autowired
    private JwtTokenUtil jwtTokenUtil;

    @Override
    protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain chain)
            throws ServletException, IOException {
        final String header = request.getHeader("Authorization");

        if (header != null && header.startsWith("Bearer ")) {
            String authToken = header.substring(7);
            System.out.println(authToken);

            try {
                String username = jwtTokenUtil.getUsernameFromToken(authToken);
                if (username != null && SecurityContextHolder.getContext().getAuthentication() == null) {
                    if (jwtTokenUtil.validateToken(authToken, username)) {
                        UsernamePasswordAuthenticationToken usernamePasswordAuthenticationToken = new UsernamePasswordAuthenticationToken(
                                username, null, null);
                        usernamePasswordAuthenticationToken
                                .setDetails(new WebAuthenticationDetailsSource().buildDetails(request));

                        SecurityContextHolder.getContext().setAuthentication(usernamePasswordAuthenticationToken);
                    }
                }
            } catch (Exception e) {
                System.out.println("Unable to get JWT Token, possibly expired");
            }
        }

        chain.doFilter(request, response);
    }
}

JwtTokenUtil.java

JwtTokenUtil.java

package com.leadwinner.sms.config.jwt;

import java.io.Serializable;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import java.util.function.Function;

import org.springframework.stereotype.Component;

import io.jsonwebtoken.Claims;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureAlgorithm;

@Component
public class JwtTokenUtil implements Serializable {
    private static final long serialVersionUID = 8544329907338151549L;
    public static final long JWT_TOKEN_VALIDITY = 5 * 60 * 60;
    private String secret = "my-secret";

    public String getUsernameFromToken(String token) {
        return getClaimFromToken(token, Claims::getSubject);
    }

    public Date getExpirationDateFromToken(String token) {
        return getClaimFromToken(token, Claims::getExpiration);
    }

    public <T> T getClaimFromToken(String token, Function<Claims, T> claimsResolver) {
        final Claims claims = getAllClaimsFromToken(token);
        return claimsResolver.apply(claims);
    }

    private Claims getAllClaimsFromToken(String token) {
        return Jwts.parser().setSigningKey(secret).parseClaimsJws(token).getBody();
    }

    private Boolean isTokenExpired(String token) {
        final Date expiration = getExpirationDateFromToken(token);
        return expiration.before(new Date());
    }

    public String generateToken(String username) {
        Map<String, Object> claims = new HashMap<>();
        return doGenerateToken(claims, username);
    }

    private String doGenerateToken(Map<String, Object> claims, String subject) {
        return "Bearer "
                + Jwts.builder().setClaims(claims).setSubject(subject).setIssuedAt(new Date(System.currentTimeMillis()))
                        .setExpiration(new Date(System.currentTimeMillis() + JWT_TOKEN_VALIDITY * 1000))
                        .signWith(SignatureAlgorithm.HS512, secret).compact();
    }

    public Boolean validateToken(String token, String usernameFromToken) {
        final String username = getUsernameFromToken(token);
        return (username.equals(usernameFromToken) && !isTokenExpired(token));
    }
}

現在 JwtSecurityConfig 過濾器似乎沒有應用于我提到的路徑.任何幫助將不勝感激.

It seems that now the JwtSecurityConfig filter is not being applied for the path I have mentioned. Any help will be appreciated.

我已經閱讀了這個問題.我也跟著.

I have already read this question. I followed the same.

Spring 安全與 Spring Boot: 將基本身份驗證與 JWT 令牌身份驗證混合使用

添加了 JwtAuthenticationTokenFilter、JwtTokenUtil

Added JwtAuthenticationTokenFilter, JwtTokenUtil

推薦答案

我得到了你的要求.

  1. 您需要在請求標頭(針對每個請求)中公開應通過 JWT 令牌訪問的 API.
  2. Web 應用程序也應通過基于表單的身份驗證機制進行保護,該機制應基于 http 會話工作.

您可以通過兩個身份驗證過濾器來實現這一點.

You can achieve this by two authentication filters.

Filter - 1:用于 Rest API (JwtAuthTokenFilter),它應該是無狀態的,并由每次在請求中發送的授權令牌標識.
Filter - 2:你需要另一個過濾器(UsernamePasswordAuthenticationFilter) 默認情況下,如果你通過 http.formLogin() 配置它,spring-security 會提供這個.這里每個請求都由關聯的會話(JSESSIONID cookie)標識.如果請求不包含有效會話,那么它將被重定向到身份驗證入口點(例如:登錄頁面).

Filter - 1: for Rest API (JwtAuthTokenFilter) which should be stateless and identified by Authorization token sent in request each time.
Filter - 2: You need another filter (UsernamePasswordAuthenticationFilter) By default spring-security provides this if you configure it by http.formLogin(). Here each request is identified by the session(JSESSIONID cookie) associated. If request does not contain valid session then it will be redirected to authentication-entry-point (say: login-page).

api-url-pattern    = "/api/**" [strictly for @order(1)]
webApp-url-pattern = "/**" [ wild card "/**" always used for higer order otherwise next order configuration becomes dead configuration]

方法

  • 使用 @EnableWebSecurity

    創建兩個內部靜態類,它們應該擴展 WebSecurityConfigurerAdapter 并使用@Configuration 和@Order 進行注釋.這里rest api配置的順序應該是1,Web應用程序配置的順序應該大于1

    Create two inner static classes which should extend WebSecurityConfigurerAdapter and annotated with @Configuration and @Order. Here order for rest api configuration should be 1 and for web application configuration order should be more than 1

    請參閱 我在此鏈接中的回答了解更多詳情,其中有解釋深度與必要的代碼.如果需要,請隨時從 github 存儲庫獲取可下載鏈接.

    Refer my answer in this link for more details which has explaination in depth with necessary code. Feel free to ask for downloadable link from github repository if required.

    限制
    在這里,兩個過濾器將并排工作(并行).我的意思是來自 Web 應用程序,即使用戶通過會話進行身份驗證,他也無法在沒有 JWT 令牌的情況下訪問 API.

    Limitation
    Here both filters will work side by side(Parellally). I mean from web application even though if a user is authenticated by session, he can not access API's without a JWT token.

    編輯
    對于 OP 的要求,他不想定義任何角色,但允許經過身份驗證的用戶訪問 API.為他的要求修改了下面的配置.

    EDIT
    For OP's requirement where he doesn't want to define any role but API access is allowed for authenticated user. For his requirement modified below configuration.

    http.csrf().disable()
    .antMatcher("/web/umgmt/**").authorizeRequests()
    .antMatcher("/web/umgmt/**").authenticated() // use this
    

    這篇關于Spring Security MultiHttpSecurity 配置使我可以執行兩種類型的身份驗證.JWT 令牌和會話 Cookie的文章就介紹到這了,希望我們推薦的答案對大家有所幫助,也希望大家多多支持html5模板網!

    【網站聲明】本站部分內容來源于互聯網,旨在幫助大家更快的解決問題,如果有圖片或者內容侵犯了您的權益,請聯系我們刪除處理,感謝您的支持!

相關文檔推薦

How to wrap text around components in a JTextPane?(如何在 JTextPane 中的組件周圍環繞文本?)
MyBatis, how to get the auto generated key of an insert? [MySql](MyBatis,如何獲取插入的自動生成密鑰?[MySql])
Inserting to Oracle Nested Table in Java(在 Java 中插入 Oracle 嵌套表)
Java: How to insert CLOB into oracle database(Java:如何將 CLOB 插入 oracle 數據庫)
Why does Spring-data-jdbc not save my Car object?(為什么 Spring-data-jdbc 不保存我的 Car 對象?)
Use threading to process file chunk by chunk(使用線程逐塊處理文件)
主站蜘蛛池模板: 日韩欧美在线不卡 | 亚洲国产精品第一区二区 | 国产高清视频 | 性做久久久久久免费观看欧美 | 国产精品99久久久久久宅男 | 人操人免费视频 | 精品一区av | 日韩三片 | 久久久91| 亚洲高清一区二区三区 | 亚洲一区二区三区在线播放 | 一级做a爰片性色毛片16 | 久草在线| 在线视频中文字幕 | 久久免费精品视频 | 一级片视频免费观看 | 国产精品99久久久久久久vr | 91.com视频| 拍真实国产伦偷精品 | 国产一区二区三区四区三区四 | 国产一二三视频在线观看 | 国产7777| 欧美成人激情 | 日韩一区二区三区精品 | 亚洲国产精品久久人人爱 | 日本人爽p大片免费看 | 国产精品久久久久久久久久 | 亚洲高清在线观看 | 观看毛片 | 欧美日韩不卡合集视频 | 精品中文字幕久久 | 精品日韩一区二区 | 久久涩涩| 国产精品久久久久久久久久免费看 | 深夜爽视频| 色网站在线免费观看 | 91精品国产综合久久精品 | 二区精品 | 97国产一区二区 | 国产精品国产精品国产专区不卡 | 黄色毛片免费 |