在这里你可以找到一个工作项目https://github.com/angeloimm/springbasicauth
我知道在 pom.xml 文件中有很多无用的依赖项,但是我从一个已经存在的项目开始,我没有时间去净化它
基本上你必须:
- 配置弹簧安全
- 配置spring mvc
- 根据spring security实现你自己的认证提供者。注意我使用了 inMemoryAuthentication。请根据自己的意愿修改
让我解释一下代码。
Spring MVC 配置:
@Configuration
@EnableWebMvc
@ComponentScan(basePackages= {"it.olegna.test.basic"})
public class WebMvcConfig implements WebMvcConfigurer {
@Override
public void configureMessageConverters(final List<HttpMessageConverter<?>> converters) {
converters.add(new MappingJackson2HttpMessageConverter());
}
}
在这里,我们不做任何其他事情,通过告诉它在哪里可以找到控制器等来配置 Spring MVC,并使用单个消息转换器; MappingJackson2HttpMessageConverter 以生成 JSON 响应
Spring 安全配置:
@Configuration
@EnableWebSecurity
@Import(value= {WebMvcConfig.class})
public class WebSecConfig extends WebSecurityConfigurerAdapter {
@Autowired private RestAuthEntryPoint authenticationEntryPoint;
@Autowired
public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
auth
.inMemoryAuthentication()
.withUser("test")
.password(passwordEncoder().encode("testpwd"))
.authorities("ROLE_USER");
}
@Override
protected void configure(HttpSecurity http) throws Exception {
http
.authorizeRequests()
.antMatchers("/securityNone")
.permitAll()
.anyRequest()
.authenticated()
.and()
.httpBasic()
.authenticationEntryPoint(authenticationEntryPoint);
}
@Bean
public PasswordEncoder passwordEncoder() {
return NoOpPasswordEncoder.getInstance();
}
}
这里我们配置 Spring Security 以便对除以 securityNone 开头的请求之外的所有请求使用 HTTP 基本身份验证。我们使用NoOpPasswordEncoder 来对提供的密码进行编码;这个 PasswrodEncoder 绝对什么都不做……它保持原样。
RestEntryPoint:
@Component
public class RestAuthEntryPoint implements AuthenticationEntryPoint {
@Override
public void commence(HttpServletRequest request, HttpServletResponse response, AuthenticationException authException) throws IOException, ServletException {
response.sendError(HttpServletResponse.SC_UNAUTHORIZED, "Unauthorized");
}
}
此入口点禁用所有不包含 Authentication 标头的请求
SimpleDto:一个非常简单的 DTO,表示来自控制器的 JSON 答案
public class SimpleDto implements Serializable {
private static final long serialVersionUID = 1616554176392794288L;
private String simpleDtoName;
public SimpleDto() {
super();
}
public SimpleDto(String simpleDtoName) {
super();
this.simpleDtoName = simpleDtoName;
}
public String getSimpleDtoName() {
return simpleDtoName;
}
public void setSimpleDtoName(String simpleDtoName) {
this.simpleDtoName = simpleDtoName;
}
}
TestBasicController:一个非常简单的控制器
@RestController
@RequestMapping(value= {"/rest"})
public class TestBasicController {
@RequestMapping(value= {"/simple"}, method= {RequestMethod.GET}, produces= {MediaType.APPLICATION_JSON_UTF8_VALUE})
public ResponseEntity<List<SimpleDto>> getSimpleAnswer()
{
List<SimpleDto> payload = new ArrayList<>();
for(int i= 0; i < 5; i++)
{
payload.add(new SimpleDto(UUID.randomUUID().toString()));
}
return ResponseEntity.ok().body(payload);
}
}
因此,如果您使用邮递员或任何其他测试人员尝试此项目,您可以有 2 个场景:
假设您要调用 URL http://localhost:8080/test_basic/rest/simple 而不传递 Authentication 标头。 HTTP 状态码将为401 Unauthorized
这意味着需要Authentication Header
通过将此标头添加到请求 Authorization Basic dGVzdDp0ZXN0cHdk 一切都很好
注意字符串dGVzdDp0ZXN0cHdk是字符串username:password的Base64编码;在我们的例子中是在 inMemoryAuthentication 中定义的test:testpwd 的 Base64 编码
希望对你有用
安杰洛
网络安全用户数据服务
为了配置 Spring 安全性以从 DB 中检索用户详细信息,您必须执行以下操作:
像这样创建一个 org.springframework.security.core.userdetails.UserDetailsService 实现:
@Service
public class UserDetailsServiceImpl implements UserDetailsService {
@Autowired
private BasicService svc;
@Override
public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
BasicUser result = svc.findByUsername(username);
if( result == null )
{
throw new UsernameNotFoundException("No user found with username "+username);
}
return result;
}
}
将它注入到spring安全配置中并像这样使用它:
public class WebSecConfig extends WebSecurityConfigurerAdapter {
@Autowired private RestAuthEntryPoint authenticationEntryPoint;
@Autowired
UserDetailsService userDetailsService;
@Autowired
public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
// auth
// .inMemoryAuthentication()
// .withUser("test")
// .password(passwordEncoder().encode("testpwd"))
// .authorities("ROLE_USER");
auth.userDetailsService(userDetailsService);
auth.authenticationProvider(authenticationProvider());
}
@Bean
public DaoAuthenticationProvider authenticationProvider() {
DaoAuthenticationProvider authenticationProvider = new DaoAuthenticationProvider();
authenticationProvider.setUserDetailsService(userDetailsService);
authenticationProvider.setPasswordEncoder(passwordEncoder());
return authenticationProvider;
}
@Override
protected void configure(HttpSecurity http) throws Exception {
http
.authorizeRequests()
.antMatchers("/securityNone")
.permitAll()
.anyRequest()
.authenticated()
.and()
.httpBasic()
.authenticationEntryPoint(authenticationEntryPoint);
}
@Bean
public PasswordEncoder passwordEncoder() {
return NoOpPasswordEncoder.getInstance();
}
}
我在我提供的 github 链接上推送了代码。在那里你可以找到一个完整的工作示例:
根据自己的情况随意调整