SpringSecurity之授權鑑權

一般系統中區分賬號角色即可,除了後臺管理這類對權限要求比較複雜的。

  • 權限表達式:
    在這裏插入圖片描述

  • 使用
    一般在類上或者方法上添加註解使用(不需要對每一個接口配置權限,一般小項目用不到,只要數據庫是邏輯刪除可恢復這種簡單的就可以使用)
    在這裏插入圖片描述
    在啓動類上添加註解:
    @EnableGlobalMethodSecurity(securedEnabled = true, jsr250Enabled = true, prePostEnabled = true)

  • 配置資源服務器
    依賴:

    <dependencies>
    	<dependency>
    		<groupId>org.springframework.boot</groupId>
    		<artifactId>spring-boot-starter-security</artifactId>
    	</dependency>
    	<dependency>
    		<groupId>org.springframework.cloud</groupId>
    		<artifactId>spring-cloud-starter-oauth2</artifactId>
    	</dependency>
    	<dependency>
    		<groupId>io.undertow</groupId>
    		<artifactId>undertow-servlet</artifactId>
    	</dependency>
    </dependencies>
    

    EnableResourceServer:

    package com.cong.security;
    
    import org.springframework.context.annotation.Configuration;
    import org.springframework.http.HttpMethod;
    import org.springframework.security.config.annotation.web.builders.HttpSecurity;
    import org.springframework.security.oauth2.config.annotation.web.configuration.EnableResourceServer;
    import org.springframework.security.oauth2.config.annotation.web.configuration.ResourceServerConfigurerAdapter;
    import org.springframework.web.cors.CorsUtils;
    
    @Configuration
    @EnableResourceServer
    public class MyResourceServerConfig extends ResourceServerConfigurerAdapter {
    
    	@Override
    	public void configure(HttpSecurity http) throws Exception {
    
    		http.authorizeRequests().antMatchers(HttpMethod.OPTIONS).permitAll();// 放行預請求
    
    		http.authorizeRequests().requestMatchers(CorsUtils::isPreFlightRequest).permitAll()// 解決瀏覽器端預請求直接放過,不作處理
    				.and().csrf().disable();// 跨站請求訪問
    	}
    }
    

    JWT配置

    package com.cong.security;
    
    import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
    import org.springframework.context.annotation.Bean;
    import org.springframework.context.annotation.Configuration;
    import org.springframework.security.oauth2.provider.token.TokenStore;
    import org.springframework.security.oauth2.provider.token.store.JwtAccessTokenConverter;
    import org.springframework.security.oauth2.provider.token.store.JwtTokenStore;
    
    @Configuration
    public class TokenStoreConfig {
    
    	/**
    	 * prefix---檢查的配置項的前綴<br>
    	 * name---配置文件中prefix串後面的參數名<br>
    	 * havingValue---值對應此配置參數的時候,當前類的所有配置生效<br>
    	 * matchIfMissing---設置爲true等同於如果配置文件中不設置任何屬性,配置文件生效<br>
    	 */
    	@Configuration
    	@ConditionalOnProperty(prefix = "my.security.oAuth2", name = "storeType", havingValue = "jwt", matchIfMissing = true)
    	public static class JwtTokenConfig {
    
    		/**
    		 * 處理token存儲
    		 */
    		@Bean
    		public TokenStore jwtTokenStore() {
    			return new JwtTokenStore(jwtAccessTokenConverter());
    		}
    
    		/**
    		 * 處理token生成邏輯
    		 */
    		@Bean
    		public JwtAccessTokenConverter jwtAccessTokenConverter() {
    			JwtAccessTokenConverter accessTokenConverter = new JwtAccessTokenConverter();
    			// 設置簽名密鑰
    			accessTokenConverter.setSigningKey("mydev");
    			return accessTokenConverter;
    		}
    	}
    }
    

    CORS簡單配置:

    package com.cong.security;
    
    import java.util.Arrays;
    import java.util.List;
    import org.springframework.core.Ordered;
    import org.springframework.core.annotation.Order;
    import org.springframework.http.HttpHeaders;
    import org.springframework.stereotype.Component;
    import org.springframework.web.cors.CorsConfiguration;
    import org.springframework.web.cors.UrlBasedCorsConfigurationSource;
    import org.springframework.web.filter.CorsFilter;
    
    @Component
    @Order(Ordered.HIGHEST_PRECEDENCE)
    public class MyCorsFilter extends CorsFilter {
    	
    	public MyCorsFilter() {
    		super(configurationSource());
    	}
    
    	public static UrlBasedCorsConfigurationSource configurationSource() {
    		CorsConfiguration corsConfig = new CorsConfiguration();
    		List<String> allowedHeaders = Arrays.asList("Authorization", "Access-Control-Allow-Origin",
    				"Access-Control-Request-Headers", "Access-Control-Request-Method", "x-auth-token", "content-type",
    				"X-Requested-With", "XMLHttpRequest");
    		List<String> exposedHeaders = Arrays.asList("Authorization", "Access-Control-Allow-Origin",
    				"Access-Control-Request-Headers", "Access-Control-Request-Method", "x-auth-token", "content-type",
    				"X-Requested-With", "XMLHttpRequest");
    		List<String> allowedMethods = Arrays.asList("POST", "GET", "DELETE", "PUT", "OPTIONS");
    		corsConfig.setAllowedHeaders(allowedHeaders);
    		corsConfig.setAllowedMethods(allowedMethods);
    		// 配置跨域請求
    		corsConfig.addExposedHeader(HttpHeaders.SET_COOKIE);
    		corsConfig.setExposedHeaders(exposedHeaders);
    		corsConfig.setMaxAge(36000L);
    		corsConfig.setAllowCredentials(true);
    		corsConfig.addAllowedOrigin("*");
    		UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
    		source.registerCorsConfiguration("/**", corsConfig);
    		return source;
    	}
    }
    

    將上面三個類提取出來到一個單獨的模塊中,這樣使用JWT無狀態登錄即可實現模塊拆分,方便業務擴展。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章