使用基本身份验证来保护Spring Boot REST API

这是我的Spring Boot Blog帖子系列的第三篇文章。 在第一篇文章中,我谈到了我使用Spring Boot创建RESTFul Services的经验。 然后我将样本扩展到
与Swagger文档集成 。 在这篇文章中,我将在安全方面扩展上述示例。

什么是API安全性

API安全性广泛,具有许多不同的定义,含义和解决方案。 API安全性中的主要关键术语是授权,身份验证,加密,联合和委派。 但是,在这里我不会谈论它们。

什么是认证

身份验证用于可靠地确定最终用户的身份,并根据正确标识的用户授予对资源的访问权限。

什么是基本身份验证

基本身份验证是对资源实施访问控制的最简单方法。 在此,HTTP用户代理在发出请求时提供用户名和密码。 当需要身份验证时,包含用户名和密码的字符串由冒号分隔,并在发送到后端之前经过Base64编码。

如何调用基本身份验证受保护的API

选项1:发送授权标头。 该值是base64编码的username:password Ex:“授权:基本Y2hhbmRhbmE6Y2hhbmRhbmE =”

curl -X GET http://localhost:8080/admin/hello/chandana -H 'authorization: Basic Y2hhbmRhbmE6Y2hhbmRhbmE='

选项2:使用网址:

curl -X GET -u username:password  http://localhost:8080/admin/hello/chandana

好的,我们讨论了一些基本的东西。 因此,让我们来看一下如何使用Spring Security保护REST API。 您可以从我的GitHub存储库下载初始示例代码(Swagger Spring Boot Project源代码)

为了使用基本的auth安全性增强我们先前的示例,首先我将在pom文件中添加“ spring-boot-starter-security”和“ spring-boot-starter-tomcat”依赖项。

<!-- --><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-security</artifactId></dependency><dependency><groupId>javax.servlet</groupId><artifactId>javax.servlet-api</artifactId><version>3.1.0</version></dependency>

下一步是使用@EnableWebSecurity批注对我们的配置类进行批注,并从WebSecurityConfigurerAdapter扩展配置类。 EnableWebSecurity批注将启用Spring-Security Web安全支持。

@Configuration
@EnableSwagger2
@EnableWebSecurity
public class ApplicationConfig extends WebSecurityConfigurerAdapter {

重写的configure(HttpSecurity)方法用于定义哪些URL路径应该受到保护,哪些不应该受到保护。 在我的示例中,不需要“ /”和“ / api”路径进行任何身份验证,并且任何其他路径(例如:“ admin”)都应使用基本身份验证进行身份验证。

@Override
protected void configure(HttpSecurity http) throws Exception {http.csrf().disable();http.authorizeRequests().antMatchers("/", "/api/**").permitAll().anyRequest().authenticated();http.httpBasic().authenticationEntryPoint(basicAuthenticationPoint);
}

在configureGlobal(AuthenticationManagerBuilder)方法中,我创建了一个内存用户存储,其中包含一个名为“ chandana”的用户。 在那里,我为内存中的用户添加了用户名,密码和userole。

@Autowiredpublic void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {auth.inMemoryAuthentication().withUser("chandana").password("chandana").roles("USER");}

除此之外,您还可以看到我已将自动装配的BasicAuthenticationPoint添加到我的配置类中。 BasicAuthenticationEntryPoint类的目的是将“ WWW-Authenticate”标头设置为响应。 因此,Web浏览器将显示一个对话框,用于基于基本身份验证机制(WWW-Authenticate标头)输入用户名和密码

然后,您可以使用“ mvn spring-boot:run”运行示例。 当您访问“ localhost:8080 / api / hello / chandana”时,调用api不需要基本身份验证。 但是,如果您尝试访问“ localhost:8080 / admin / hello / chandana”,则需要提供基本的身份验证凭据才能访问资源。

AppConfig类:

package com.chandana.helloworld.config;  import org.springframework.beans.factory.annotation.Autowired;  import org.springframework.context.annotation.Bean;  import org.springframework.context.annotation.Configuration;  import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;  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 springfox.documentation.builders.ApiInfoBuilder;  import springfox.documentation.builders.PathSelectors;  import springfox.documentation.builders.RequestHandlerSelectors;  import springfox.documentation.service.ApiInfo;  import springfox.documentation.service.Contact;  import springfox.documentation.spi.DocumentationType;  import springfox.documentation.spring.web.plugins.Docket;  import springfox.documentation.swagger2.annotations.EnableSwagger2;  @Configuration  @EnableSwagger2  @EnableWebSecurity  public class ApplicationConfig extends WebSecurityConfigurerAdapter {  @Autowired  private BasicAuthenticationPoint basicAuthenticationPoint;  @Bean  public Docket api() {  return new Docket(DocumentationType.SWAGGER_2)  .apiInfo(getApiInfo())  .select()  .apis(RequestHandlerSelectors.basePackage("com.chandana.helloworld.controllers"))  .paths(PathSelectors.any())  .build();  }  @Override  protected void configure(HttpSecurity http) throws Exception {  http.csrf().disable();  http.authorizeRequests().antMatchers("/", "/api/**").permitAll()  .anyRequest().authenticated();  http.httpBasic().authenticationEntryPoint(basicAuthenticationPoint);  }  private ApiInfo getApiInfo() {  Contact contact = new Contact("Chandana Napagoda", "http://blog.napagoda.com", "cnapagoda@gmail.com");  return new ApiInfoBuilder()  .title("Example Api Title")  .description("Example Api Definition")  .version("1.0.0")  .license("Apache 2.0")  .licenseUrl("http://www.apache.org/licenses/LICENSE-2.0")  .contact(contact)  .build();  }  @Autowired  public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {  auth.inMemoryAuthentication().withUser("chandana").password("chandana").roles("USER");  }  }

BasicAuthenticationEntryPoint类:

package com.chandana.helloworld.config;  import org.springframework.security.core.AuthenticationException;  import org.springframework.security.web.authentication.www.BasicAuthenticationEntryPoint;  import org.springframework.stereotype.Component;  import java.io.IOException;  import java.io.PrintWriter;  import javax.servlet.ServletException;  import javax.servlet.http.HttpServletRequest;  import javax.servlet.http.HttpServletResponse;  @Component  public class BasicAuthenticationPoint extends BasicAuthenticationEntryPoint {  @Override  public void commence(HttpServletRequest request, HttpServletResponse response, AuthenticationException authEx)  throws IOException, ServletException {  response.addHeader("WWW-Authenticate", "Basic realm=" +getRealmName());  response.setStatus(HttpServletResponse.SC_UNAUTHORIZED);  PrintWriter writer = response.getWriter();  writer.println("HTTP Status 401 - " + authEx.getMessage());  }  @Override  public void afterPropertiesSet() throws Exception {  setRealmName("Chandana");  super.afterPropertiesSet();  }  }

您也可以从我的GitHub存储库下载Spring Boot Basic Auth Project源代码。

翻译自: https://www.javacodegeeks.com/2017/10/secure-spring-boot-rest-api-using-basic-authentication.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/349225.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

使用2.26内核的linux,介绍linux 2.6.9-42内核升级到linux 2.6.26-42的方法

介绍linux 2.6.9-42内核升级到linux 2.6.26-42的方法来源&#xff1a;互联网作者&#xff1a;佚名时间&#xff1a;2013-04-10 13:32这篇升级Linux内容的文章&#xff0c;是基于Red Hat的Linux版本&#xff0c;从linux 2.6.9-42内核升级到linux 2.6.26-42的方法&#xff0c;对于…

python xlwt xlrd 写入一行_自己总结python用xlrd\xlwt读写excel

1.首先安装xlrd\xlwt模块xlrd模块下载地址:https://pypi.python.org/pypi/xlrdxlwt模块下载地址:https://pypi.python.org/pypi/xlwtlinux 安装命令 python setup.py installwindos 安装命令 setup.py install2.使用方法大全基础方法推荐请看这里:http://blog.csdn.net/mr__fan…

linux时间路径,关于linux中的时间 时区问题

本文部分来源于&#xff1a; http://hi.baidu.com/peruke/blog/item/b8de06ec6a04583b27979132.html系统是fedora&#xff1a;glibc实现了从RTC时间到人可读时间的一个转换&#xff0c;一般系统不适用 环境变量TZ进行时区的设置&#xff0c;因为环境变量存在一些缺陷&#xff…

Java命令行界面(第1部分):Apache Commons CLI

尽管我通常使用Groovy编写要从命令行运行的JVM托管脚本&#xff0c;但是有时候我需要解析Java应用程序中的命令行参数&#xff0c;并且有很多库可供Java开发人员用来解析命令行参数。 在本文中&#xff0c;我将介绍这些Java命令行解析库中最著名的一种&#xff1a; Apache Comm…

python自带的idle输入python_打开python自带IDLE出的问题

打开python自带IDLE编辑器时出的问题IDLE cant bind to a TCP/IP port, which is necessary tocommunicate with its Python execution server. This might bebecause no networking is installed on this computer. Run IDLEwith the -n command line switch to start without…

linux 虚拟机新增磁盘,linux(虚拟机)下新增磁盘配置

Linux的硬盘识别:(1)”fdisk -l”命令可以列出系统中当前连接的硬盘设备和分区信息.新硬盘没有分区信息,则只显示硬盘大小信息.(2)创建新硬盘分区命令参数&#xff1a;fdisk可以用m命令来看fdisk命令的内部命令&#xff1b;a&#xff1a;命令指定启动分区&#xff1b;d&#xf…

丙烯怎么做成流体丙烯_韧性好强度高的聚丙烯复合材料怎么做?让人工智能来帮忙...

01背景介绍聚丙烯(PP)是一种应用广泛的通用塑料&#xff0c;价格便宜、力学性能好、热稳定性高&#xff0c;在机械、汽车、电子电器、建筑、纺织、包装和食品工业等领域应用广泛。聚丙烯韧性和冲击强度不高&#xff0c;限制了它的应用。加入热塑性弹性体(TPE)&#xff0c;如苯乙…

1.x到2.x的迁移:可观察与可观察:RxJava FAQ

标题不是错误。 rx.Observable 1.x的io.reactivex.Observable与2.x的io.reactivex.Observable完全不同。 盲目升级rx依赖关系并重命名项目中的所有导入将进行编译&#xff08;稍作更改&#xff09;&#xff0c;但不能保证相同的行为。 在项目的早期&#xff0c; Observable in …

linux 线程 拷贝,linux下实现多线程拷贝命令

实现多线程拷贝命令,如&#xff1a;./multithread_copy srcfile destfile N(拷贝线程个数)难点&#xff1a;内存映射mmap。给每一个线程合理的分配任务。多线程的实现。具体的实现代码如下&#xff1a;/********************************************************************…

vivado安装_Vivado下载与安装指南

Vivado下载与安装指南目前&#xff0c;vivado已推出2019.1版本&#xff0c;实验室所安装的为2018.3版本&#xff0c;由于软件向下兼容的特性&#xff0c;建议安装2018版本&#xff0c;若安装2019版本&#xff0c;请自带笔记本&#xff0c;安装过程与之前没有差别&#xff0c;这…

linux中kafka主题修改分区,kafka_2.11-2.0.0的部署与配置修改

1 [yunmini01 config]$ pwd2 /app/kafka/config3 [yunmini01 config]$ vim server.properties4 ############################# Server Basics #############################5 # 每一个broker在集群中的唯一标示★★★6 # 比如mini01 为0 mini02 为1 mini03 为27 broker.id089…

python中字符串乘法_python leetcode 字符串相乘实例详解

给定两个以字符串形式表示的非负整数 num1 和 num2 &#xff0c;返回 num1 和 num2 的乘积&#xff0c;它们的乘积也表示为字符串形式。示例 1:输入: num1 "2", num2 "3"输出: "6"示例 2:输入: num1 "123", num2 "456&quo…

嵌入式基于linux电机控制器,基于嵌入式Linux的移动机器人控制系统

使用select机制监控是否语音识别结果&#xff0c;在超出等待时间后&#xff0c;会退出等待并重新初始化语音模块LD3320&#xff0c;释放公共资源&#xff0c;这样也使得系统能够及时响应LD3320的MP3播放功能&#xff0c;避免了在长时间没有语音识别结果时&#xff0c;系统进入卡…

jdk8运行jdk7的代码_即使在jdk中也有错误的代码

jdk8运行jdk7的代码Java 7&#xff0c;TreeSet和NullPointerException。 最近&#xff0c;我尝试用Java 7编译一个用Java 6开发的项目。在执行测试过程中发生了很多有趣的事情&#xff0c;在Java 6中使用Java 7平稳运行的测试失败了&#xff01; 因此&#xff0c;我必须理解为什…

zen of python什么意思_如何理解「The Zen of Python」?

import thisThe Zen of Python, by Tim PetersPython之禅 &#xff0c;by Tim PetersBeautiful is better than ugly.优美好于丑陋(Python 以优美的代码为其风格&#xff0c;不要写丑陋的代码)Explicit is better than implicit.明了好于隐晦(Python的每一行代码、每一个变量、…

linux用pipe创建的文件类型,linux文件类型之 管道

inux管道管道是Linux中很重要的一种通信方式,是把一个程序的输出直接连接到另一个程序的输入,常说的管道多是指无名管道,无名管道只能用于具有亲缘关系的进程之间&#xff0c;这是它与有名管道的最大区别。有名管道叫namedpipe或者FIFO(先进先出)&#xff0c;可以用函数mkfifo(…

Spring Webflux – Kotlin DSL –实现的演练

在先前的博客文章中&#xff0c;我描述了Spring Web Framework中的响应式编程支持Spring Webflux如何使用基于Kotlin的DSL使用户能够以非常直观的方式描述路由。 在这里&#xff0c;我想探索一些底层实现。 描述一组端点的样本DSL看起来像这样&#xff1a; package sample.ro…

python 正则表达式提取数据_Python爬虫教程-19-数据提取-正则表达式(re)

本篇主页内容&#xff1a;match的基本使用&#xff0c;search的基本使用&#xff0c;findall,finditer的基本使用&#xff0c;匹配中文&#xff0c;贪婪与非贪婪模式Python爬虫教程-19-数据提取-正则表达式(re)正则表达式&#xff1a;一套规则&#xff0c;可以在字符串文本中进…

c语言作业请输入一个运算符,C语言书面作业1(有答案版)..doc

C语言书面作业1(有答案版).书面作业1(数据类型、变量、输入/输出、运算符与表达式、选择结构、循环结构)一、判断题&#xff1a;在正确的说法前面填写T&#xff0c;在错误的说法前面填写F(每题1分)[得分&#xff1a; ]()()()()标识符中可以出现下划线但它不可以放在标识符的开头…

windows server 驱动精灵_还在用Windows文件共享?我来教你一键摆脱Windows海量小文件使用和备份的噩梦...

每当我问到客户&#xff0c;“你用什么存储产品作为文件共享&#xff1f;”经常听到的一个答案(自豪滴)是&#xff0c;“文件共享需要存储么&#xff1f;我们用Windows就可以做到。”Windows就是个百宝箱&#xff0c;什么都能往里装&#xff0c;就像你家冰箱一样。众所周知&…