jac*_*m98 6 http spring-security basic-authentication spring-boot
我已经构建了一个网络服务器,并试图对其进行密码保护。我正在尝试使用 Spring Boot 设置基本身份验证。到目前为止,这是我的配置文件:
@Configuration
@EnableWebSecurity
public class SecurityConfiguration extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
http.authorizeRequests()
.antMatchers("/", "/v1/occupancy/*")
.permitAll()
.anyRequest()
.authenticated()
.and()
.httpBasic();
}
}
Run Code Online (Sandbox Code Playgroud)
这按预期工作并保护我的 GET 端点之一,使我能够进行身份验证。
但是,对于 POST 端点,这不起作用。端点看起来像这样:
@RequestMapping(path = "/v1/admin/repository")
public class RepositoryOptionsController {
private final EstablishmentOptionsRepositoryService establishmentOptionsRepositoryService;
private final SubAreaOptionsRepositoryService subAreaOptionsRepositoryService;
@PostMapping("/establishment/options")
public ResponseEntity<String> postEstablishmentOption(@RequestBody OptionsRequestDto body) {
Run Code Online (Sandbox Code Playgroud)
当我做
curl -X POST "http://localhost:8080/v1/admin/repository/establishment/options" -u root -v -d "{...}"
Run Code Online (Sandbox Code Playgroud)
我明白了
Enter host password for user 'root':
Note: Unnecessary use of -X or --request, POST is already inferred.
* Trying ::1...
* TCP_NODELAY set
* Connected to localhost (::1) port 8080 (#0)
* Server auth using Basic with user 'root'
> POST /v1/admin/repository/establishment/options HTTP/1.1
> Host: localhost:8080
> Authorization: Basic cm9vdDpyb290
> User-Agent: curl/7.64.1
> Accept: */*
> Content-Length: 271
> Content-Type: application/x-www-form-urlencoded
>
* upload completely sent off: 271 out of 271 bytes
< HTTP/1.1 401
< Set-Cookie: JSESSIONID=6E1CBD875597C83E6DEB794986050631; Path=/; HttpOnly
< X-Content-Type-Options: nosniff
< X-XSS-Protection: 1; mode=block
< Cache-Control: no-cache, no-store, max-age=0, must-revalidate
< Pragma: no-cache
< Expires: 0
< X-Frame-Options: DENY
* Authentication problem. Ignoring this.
< WWW-Authenticate: Basic realm="Realm"
< Content-Length: 0
< Date: Sun, 27 Sep 2020 15:29:13 GMT
<
* Connection #0 to host localhost left intact
* Closing connection 0
Run Code Online (Sandbox Code Playgroud)
相同的用户/密码组合在 GET 上运行没有问题。做什么?
httpBasic原因是和的 CSRF 防御默认开启formLogin。因为您的POST不包含 CSRF 令牌,所以 Spring Security 拒绝它。
您可以通过更改配置以允许端点来更好地了解这一点/error:
http
.authorizeRequests()
.antMatchers("/", "/v1/occupancy/**", "/error").permitAll()
// ...
Run Code Online (Sandbox Code Playgroud)
然后,当您提交 时POST,您将看到与 CSRF 令牌拒绝相关的 403。
如果您的 REST API 不是面向前端的,那么您也许可以关闭 CSRF。实现此目的的一种方法是禁用适当的端点:
http
.authorizeRequests()
// ...
.and()
.csrf()
.ignoringAntMatchers("/v1/admin/repository/establishment/options")
// ...
Run Code Online (Sandbox Code Playgroud)
如果是面向前端的,那么适当的做法是准备前端将 CSRF 令牌返回给请求。
配置需要更多步骤。
配置字符串安全性
@Configuration @EnableWebSecurity @EnableTransactionManagement 公共类 SecurityConfiguration 扩展 WebSecurityConfigurerAdapter {
@Autowired
private UserDetailServiceImpl userService;
@Autowired
public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception{
auth.userDetailsService(userService);
}
@Override
protected void configure(HttpSecurity http) throws Exception {
http.authorizeRequests()
.antMatchers("/webjars/**", "/styles/**", "/vendors/**", "/node_modules/**", "/app/**",
"/assets/**", "/api/channel/**", "/jobs/**").permitAll()
.anyRequest().authenticated()
.and()
.formLogin().loginPage("/login").permitAll()
.and()
.logout().logoutSuccessUrl("/login?logout").permitAll()
.and()
.csrf().disable();
}
Run Code Online (Sandbox Code Playgroud)
}
实现 UserDetailsService @Service 公共类 UserDetailServiceImpl 实现 UserDetailsService{ @Autowired UtentiRepostitory utentiRepository;
@Override
public UserDetails loadUserByUsername(String nomeUtente) throws UsernameNotFoundException {
try {
String userId = nomeUtente;
Utente utente = utentiRepository.findById(userId).get();
UserDetailsImp user = new UserDetailsImp(utente);
user.username = nomeUtente;
user.password = utente.getPasswd();
return user;
} catch (Exception e) {
throw new UsernameNotFoundException(nomeUtente);
}
}
Run Code Online (Sandbox Code Playgroud)
您在 Spring Security 配置中引用的此服务包含生成实现 UserDetails 接口的对象的所有角色
实现用户详细信息接口
公共类 UserDetailsImp 实现 UserDetails{
/**
*
*/
private static final long serialVersionUID = 1L;
String password;
String username;
public Utente utente;
public UserDetailsImp(Utente utente) {
this.utente = utente;
}
@Override
public Collection<? extends GrantedAuthority> getAuthorities() {
List<GrantedAuthority> res = new ArrayList<>();
res.add(new SimpleGrantedAuthority("ROLE_MENU"));
return res;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
@Override
public boolean isAccountNonExpired() {
return true;
}
@Override
public boolean isAccountNonLocked() {
return true;
}
@Override
public boolean isCredentialsNonExpired() {
return true;
}
@Override
public boolean isEnabled() {
return true;
}
public String getDenominazione() {
return utente.getDenominazione();
}
public Utente getUtente() {
return utente;
}
public void setUtente(Utente utente) {
this.utente = utente;
}
Run Code Online (Sandbox Code Playgroud)
}
就我而言@Autowired UtentiRepostitory utentiRepository; 是一个从用户数据库读取数据的存储库,但您可以使用您喜欢的任何机制。现在 Spring 安全性已设置。
然后需要在登录页面添加一个表单
<form class="form-horizontal" id="loginForm" th:action="@{/login}" method="post">
<input type="text" name="username">
<input type="password" name="password">
</form>
Run Code Online (Sandbox Code Playgroud)
不要添加 thymeleaf springsecurity 依赖项。我希望这会有所帮助
| 归档时间: |
|
| 查看次数: |
4680 次 |
| 最近记录: |