Spring Boot实战之Filter实现简单的Http Basic认证

Spring Boot实战之Filter


本文在上一篇文章http://blog.csdn.net/sun_t89/article/details/51912905 的基础上,给每个rest接口上添加过滤器,使用过滤器实现简单的Http Basic认证


1、Filter功能

filter功能,它使用户可以改变一个 request和修改一个response. Filter 不是一个servlet,它不能产生一个response,它能够在一个request到达servlet之前预处理request,也可以在离开 servlet时处理response.换种说法,filter其实是一个”servlet chaining”(servlet 链).
一个Filter包括:
1)、在servlet被调用之前截获;
2)、在servlet被调用之前检查servlet request;
3)、根据需要修改request头和request数据;
4)、根据需要修改response头和response数据;
5)、在servlet被调用之后截获.


2、定义自己的过滤器

新增HTTPBasicAuthorizeAttribute.java

如果请求的Header中存在Authorization: Basic 头信息,且用户名密码正确,则继续原来的请求,否则返回没有权限的错误信息

[java]  view plain  copy
  1. package com.xiaofangtech.sunt.filter;  
  2.   
  3. import java.io.IOException;  
  4.   
  5. import javax.servlet.Filter;  
  6. import javax.servlet.FilterChain;  
  7. import javax.servlet.FilterConfig;  
  8. import javax.servlet.ServletException;  
  9. import javax.servlet.ServletRequest;  
  10. import javax.servlet.ServletResponse;  
  11. import javax.servlet.http.HttpServletRequest;  
  12. import javax.servlet.http.HttpServletResponse;  
  13.   
  14. import com.fasterxml.jackson.databind.ObjectMapper;  
  15. import com.xiaofangtech.sunt.utils.ResultMsg;  
  16. import com.xiaofangtech.sunt.utils.ResultStatusCode;  
  17. import sun.misc.BASE64Decoder;  
  18.   
  19. @SuppressWarnings("restriction")  
  20. public class HTTPBasicAuthorizeAttribute implements Filter{  
  21.       
  22.     private static String Name = "test";  
  23.     private static String Password = "test";  
  24.   
  25.     @Override  
  26.     public void destroy() {  
  27.         // TODO Auto-generated method stub  
  28.           
  29.     }  
  30.   
  31.     @Override  
  32.     public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)  
  33.             throws IOException, ServletException {  
  34.         // TODO Auto-generated method stub  
  35.           
  36.         ResultStatusCode resultStatusCode = checkHTTPBasicAuthorize(request);  
  37.         if (resultStatusCode != ResultStatusCode.OK)  
  38.         {  
  39.             HttpServletResponse httpResponse = (HttpServletResponse) response;  
  40.             httpResponse.setCharacterEncoding("UTF-8");    
  41.             httpResponse.setContentType("application/json; charset=utf-8");   
  42.             httpResponse.setStatus(HttpServletResponse.SC_UNAUTHORIZED);  
  43.   
  44.             ObjectMapper mapper = new ObjectMapper();  
  45.               
  46.             ResultMsg resultMsg = new ResultMsg(ResultStatusCode.PERMISSION_DENIED.getErrcode(), ResultStatusCode.PERMISSION_DENIED.getErrmsg(), null);  
  47.             httpResponse.getWriter().write(mapper.writeValueAsString(resultMsg));  
  48.             return;  
  49.         }  
  50.         else  
  51.         {  
  52.             chain.doFilter(request, response);  
  53.         }  
  54.     }  
  55.   
  56.     @Override  
  57.     public void init(FilterConfig arg0) throws ServletException {  
  58.         // TODO Auto-generated method stub  
  59.           
  60.     }  
  61.       
  62.     private ResultStatusCode checkHTTPBasicAuthorize(ServletRequest request)  
  63.     {  
  64.         try  
  65.         {  
  66.             HttpServletRequest httpRequest = (HttpServletRequest)request;  
  67.             String auth = httpRequest.getHeader("Authorization");  
  68.             if ((auth != null) && (auth.length() > 6))  
  69.             {  
  70.                 String HeadStr = auth.substring(05).toLowerCase();  
  71.                 if (HeadStr.compareTo("basic") == 0)  
  72.                 {  
  73.                     auth = auth.substring(6, auth.length());    
  74.                     String decodedAuth = getFromBASE64(auth);  
  75.                     if (decodedAuth != null)  
  76.                     {  
  77.                         String[] UserArray = decodedAuth.split(":");  
  78.                           
  79.                         if (UserArray != null && UserArray.length == 2)  
  80.                         {  
  81.                             if (UserArray[0].compareTo(Name) == 0  
  82.                                     && UserArray[1].compareTo(Password) == 0)  
  83.                             {  
  84.                                 return ResultStatusCode.OK;  
  85.                             }  
  86.                         }  
  87.                     }  
  88.                 }  
  89.             }  
  90.             return ResultStatusCode.PERMISSION_DENIED;  
  91.         }  
  92.         catch(Exception ex)  
  93.         {  
  94.             return ResultStatusCode.PERMISSION_DENIED;  
  95.         }  
  96.           
  97.     }  
  98.       
  99.     private String getFromBASE64(String s) {    
  100.         if (s == null)    
  101.             return null;    
  102.         BASE64Decoder decoder = new BASE64Decoder();    
  103.         try {    
  104.             byte[] b = decoder.decodeBuffer(s);    
  105.             return new String(b);    
  106.         } catch (Exception e) {    
  107.             return null;    
  108.         }    
  109.     }  
  110.   
  111. }  


3、在SpringRestApplication类中注册过滤器,给user/*都加上http basic认证过滤器

[java]  view plain  copy
  1. package com.xiaofangtech.sunt;  
  2.   
  3. import java.util.ArrayList;  
  4. import java.util.List;  
  5.   
  6. import org.springframework.boot.SpringApplication;  
  7. import org.springframework.boot.autoconfigure.SpringBootApplication;  
  8. import org.springframework.boot.context.embedded.FilterRegistrationBean;  
  9. import org.springframework.context.annotation.Bean;  
  10.   
  11. import com.xiaofangtech.sunt.filter.HTTPBasicAuthorizeAttribute;  
  12.   
  13. @SpringBootApplication  
  14. public class SpringRestApplication {  
  15.   
  16.     public static void main(String[] args) {  
  17.         SpringApplication.run(SpringRestApplication.class, args);  
  18.     }  
  19.       
  20.     @Bean  
  21.     public FilterRegistrationBean  filterRegistrationBean() {  
  22.         FilterRegistrationBean registrationBean = new FilterRegistrationBean();  
  23.         HTTPBasicAuthorizeAttribute httpBasicFilter = new HTTPBasicAuthorizeAttribute();  
  24.         registrationBean.setFilter(httpBasicFilter);  
  25.         List<String> urlPatterns = new ArrayList<String>();  
  26.         urlPatterns.add("/user/*");  
  27.         registrationBean.setUrlPatterns(urlPatterns);  
  28.         return registrationBean;  
  29.     }  
  30. }  


4、测试

代码中固定用户名密码都为test,所以对接口进行请求时,需要添加以下认证头信息

Authorization: Basic dGVzdDp0ZXN0

dGVzdDp0ZXN0 为 test:test 经过base64编码后的结果


如果未添加认证信息或者认证信息错误,返回没有权限的错误信息




当认证信息正确,返回请求结果



当然可以!下面是一个简单的示例,演示如何在Spring Gateway中集成Spring Security: 首先,您需要在项目的pom.xml文件中添加以下依赖项: ```xml<dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-gateway</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-security</artifactId> </dependency> ``` 然后,创建一个Spring Security配置类,用于配置安全规则和认证管理器。这是一个示例配置类: ```java@Configuration@EnableWebFluxSecuritypublic class SecurityConfig { @Bean public SecurityWebFilterChain securityWebFilterChain(ServerHttpSecurity http) { return http .authorizeExchange() .pathMatchers("/api/public/**").permitAll() .anyExchange().authenticated() .and() .httpBasic() .and() .build(); } @Bean public ReactiveAuthenticationManager authenticationManager() { UserDetails user = User.withDefaultPasswordEncoder() .username("admin") .password("password") .roles("ADMIN") .build(); return new UserDetailsRepositoryReactiveAuthenticationManager(new MapReactiveUserDetailsService(user)); } } ``` 在这个配置中,我们定义了一个规则,允许访问`/api/public/**`的路径,其他路径需要进行身份验证。`UserDetailsRepositoryReactiveAuthenticationManager`用于验证用户凭据,并使用基于内存的用户存储。 接下来,创建一个Spring Gateway配置类,用于配置路由规则和过滤器。这是一个示例配置类: ```java@Configurationpublic class GatewayConfig { @Bean public RouteLocator customRouteLocator(RouteLocatorBuilder builder) { return builder.routes() .route("api_route", r -> r.path("/api/**") .filters(f -> f.filter(new AuthFilter())) .uri("http://your-backend-service")) .build(); } } ``` 在这个配置中,我们定义了一个路由规则,将以`/api/**`开头的请求转发到后端服务。我们还添加了一个名为`AuthFilter`的过滤器,用于在请求被转发之前进行身份验证。 最后,创建一个自定义过滤器类来执行身份验证逻辑。这是一个示例过滤器类: ```javapublic class AuthFilter implements GatewayFilter, Ordered { private static final String AUTHORIZATION_HEADER = "Authorization"; private static final String BEARER_PREFIX = "Bearer "; @Override public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) { String token = extractTokenFromRequest(exchange.getRequest()); if (token != null && isValidToken(token)) { // 身份验证通过,继续处理请求 return chain.filter(exchange); } else { // 身份验证失败,返回未授权的响应 exchange.getResponse().setStatusCode(HttpStatus.UNAUTHORIZED); return exchange.getResponse().setComplete(); } } private String extractTokenFromRequest(ServerHttpRequest request) { List<String> headers = request.getHeaders().get(AUTHORIZATION_HEADER); if (headers != null && !headers.isEmpty()) { String headerValue = headers.get(0); if (headerValue.startsWith(BEARER_PREFIX)) { return headerValue.substring(BEARER_PREFIX.length()); } } return null; } private boolean isValidToken(String token) { // 在此处验证token的有效性,可以根据实际需求进行实现 // 返回true表示token有效,返回false表示token无效 return true; } @Override public int getOrder() { return Ordered.HIGHEST_PRECEDENCE; } } ``` 在这个过滤器中,我们从请求中提取出Authorization头部中的Bearer令牌,并验证其有效性。根据实际需求,您可以自定义身份验证逻辑。 以上就是一个简单Spring Gateway集成Spring Security的示例。您可以根据自己的需求进行进一步的定制和扩展。希望对您有所帮助!
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值