英文:
Why authorization doesn't work and there is no access to the page?
问题
I'll provide a translation of the code and text you've provided without the code parts:
Link to my code. Through Postman, I make a request for user registration, it appears in the database, everything is fine, then in the special tab "Authorization" I enter in Postman, select 'Basic auth,' enter the data (user name and password), for example, the user name: petya@mail.ru and password: petya. Make a request to: 'http://localhost:8080/landlord/1'. You need to change the role from 'TENANT' to 'LANDLORD'. But I get an error in Postman, and nothing changes in the database. I understand that authorization does not work, maybe I wrote something wrong in the SecurityConfig file?
<html lang="en">
<head>
<meta charset="utf-8">
<title>Login Customer</title>
</head>
<body>
<div class="container">
<form class="form-signin" method="post" action="/auth/login">
<h2 class="form-signin-heading">Login</h2>
<p>
<label for="username">Username</label>
<input type="text" id="username" name="username" class="form-control" placeholder="Username" required>
</p>
<p>
<label for="password">Password</label>
<input type="password" id="password" name="password" class="form-control" placeholder="Password" required>
</p>
<button class="btn btn-lg btn-primary btn-block" type="submit">Sign in</button>
</form>
</div>
</body>
</html>
SecurityConfig:
@Configuration
@EnableWebSecurity
@EnableGlobalMethodSecurity(prePostEnabled = true)
public class SecurityConfig extends WebSecurityConfigurerAdapter {
private final UserDetailsService userDetailsService;
@Autowired
public SecurityConfig(@Qualifier("userDetailsServiceImpl") UserDetailsService userDetailsService) {
this.userDetailsService = userDetailsService;
}
@Override
protected void configure(HttpSecurity http) throws Exception {
http
.csrf().disable()
.authorizeRequests()
.antMatchers("/").permitAll()
.antMatchers("/user/registration").permitAll()
.anyRequest()
.authenticated()
.and()
.formLogin()
.loginPage("/auth/login").permitAll()
.defaultSuccessUrl("/auth/success")
.and()
.logout()
.logoutRequestMatcher(new AntPathRequestMatcher("/auth/logout", "POST"))
.invalidateHttpSession(true)
.clearAuthentication(true)
.deleteCookies("JSESSIONID")
.logoutSuccessUrl("/auth/login");
}
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.authenticationProvider(daoAuthenticationProvider());
}
@Bean
protected PasswordEncoder passwordEncoder() {
return new BCryptPasswordEncoder(12);
}
@Bean
protected DaoAuthenticationProvider daoAuthenticationProvider() {
DaoAuthenticationProvider daoAuthenticationProvider = new DaoAuthenticationProvider();
daoAuthenticationProvider.setPasswordEncoder(passwordEncoder());
daoAuthenticationProvider.setUserDetailsService(userDetailsService);
return daoAuthenticationProvider;
}
}
If you need further assistance or specific translations, please let me know.
英文:
Link my code. Through Postman, I make a request for user registration, it appears in the database, everything is fine, then in the special tab "Authorization" I enter in Postman, select Basic auth
, enter the data (user name and password), for example, the user name : petya@mail.ru and password: petya Make a request to: http://localhost:8080/landlord/1
You need to change the role from TENANT
to LANDLORD
. But I get an error in Postman and nothing changes in the database. I understand that authorization does not work, maybe I wrote something wrong in the SecurityConfig file?
<html lang = "en">
<head>
<meta charset = "utf-8">
<title> Login Customer </title>
</head>
<body>
<div class = "container">
<form class = "form-signin" method = "post" action = "/ auth / login">
<h2 class = "form-signin-heading"> Login </h2>
<p>
<label for = "username"> Username </label>
<input type = "text" id = "username" name = "username" class = "form-control" placeholder = "Username" required>
</p>
<p>
<label for = "password"> Password </label>
<input type = "password" id = "password" name = "password" class = "form-control" placeholder = "Password" required>
</p>
<button class = "btn btn-lg btn-primary btn-block" type = "submit"> Sign in </button>
</form>
</div>
</body>
</html>
SecurityConfig
@Configuration
@EnableWebSecurity
@EnableGlobalMethodSecurity(prePostEnabled = true)
public class SecurityConfig extends WebSecurityConfigurerAdapter {
private final UserDetailsService userDetailsService;
@Autowired
public SecurityConfig(@Qualifier("userDetailsServiceImpl") UserDetailsService userDetailsService) {
this.userDetailsService = userDetailsService;
}
@Override
protected void configure(HttpSecurity http) throws Exception {
http
.csrf().disable()
.authorizeRequests()
/** На какие страницы человек имеет доступы */
.antMatchers("/").permitAll()
.antMatchers("/user/registration").permitAll()
.anyRequest()
.authenticated()
.and()
.formLogin()
.loginPage("/auth/login").permitAll()
.defaultSuccessUrl("/auth/success")
.and()
.logout()
.logoutRequestMatcher(new AntPathRequestMatcher("/auth/logout", "POST"))
.invalidateHttpSession(true)
.clearAuthentication(true)
.deleteCookies("JSESSIONID")
.logoutSuccessUrl("/auth/login");
}
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.authenticationProvider(daoAuthenticationProvider());
}
@Bean
protected PasswordEncoder passwordEncoder() {
return new BCryptPasswordEncoder(12);
}
@Bean
protected DaoAuthenticationProvider daoAuthenticationProvider() {
DaoAuthenticationProvider daoAuthenticationProvider = new DaoAuthenticationProvider();
daoAuthenticationProvider.setPasswordEncoder(passwordEncoder());
daoAuthenticationProvider.setUserDetailsService(userDetailsService);
return daoAuthenticationProvider;
}
}
答案1
得分: 0
Answer: 我没有这样的可能性,或者说它没有被实现,我不知道是否可能创建这样的东西。但我怀疑这是真实的。
首先,选择是否要创建带前端或不带前端的应用。如果不带前端,那么你只需要使用Rest控制器(我已经开始做了),并且可以从这个和这个链接获取授权。接下来,在Postman中,使用请求体发起一个Post请求 - 这将是你的授权。注意务必阅读我附上的链接上的文章,它们会详细告诉你一切,我这里只有可能有问题的代码部分。还要阅读那里写的评论,特别是在英语网站上,有关获取“authenticationManager”的问题在那里有答案。我要提前说一下,它的方法必须在SecurityConfig类中注册。
希望我的答案能帮助某人并减轻他们的压力。
现在授权新方法的代码如下:
@PostMapping("/login")
public String getLoginPage(@RequestBody UserDto userDto) {
userService.loginUser(userDto);
return "login";
}
你可以注意到我接受了UserDto,在其中包括:
@NotNull
@NotEmpty
private String first_name;
@NotNull
@NotEmpty
private String last_name;
@NotNull
@NotEmpty
private String password;
@NotNull
@NotEmpty
private String email;
这是授权检查的代码:
public void loginUser(UserDto accountDto) {
UsernamePasswordAuthenticationToken authReq
= new UsernamePasswordAuthenticationToken(accountDto.getEmail(), accountDto.getPassword());
Authentication auth = authenticationManager.authenticate(authReq);
SecurityContext sc = SecurityContextHolder.getContext();
sc.setAuthentication(auth);
}
英文:
Answer: I don't have such a possibility, or rather it is not implemented, I don't know if it is possible to create such a thing or not. But I suspect it's real.
Initially, choose whether you want to create with or without a front, if without, then you only need Rest controllers(I started doing this) and you can get authorization from this and this links. Next, in Postman, make a Post request with the body - this will be your authorization. !ATTENTION! Be sure to read the articles on the links that I attached above, they tell you everything in detail, I do not have the full version of the code here, only the one that may have questions. Also read the comments that are written there, especially on the English-language site, there is an answer to the question about where to get the "authenticationManager". I say right away, its method must be registered in the SecurityConfig class.
I hope that my answer will help someone and save their nerves.
Code of what the new method for authorization looks like now:
@PostMapping("/login")
public String getLoginPage(@RequestBody UserDto userDto) {
userService.loginUser(userDto);
return "login";
}
You can notice that I accept UserDto, in it I have:
@NotNull
@NotEmpty
private String first_name;
@NotNull
@NotEmpty
private String last_name;
@NotNull
@NotEmpty
private String password;
@NotNull
@NotEmpty
private String email;
And here is the authorization check itself:
public void loginUser(UserDto accountDto) {
UsernamePasswordAuthenticationToken authReq
= new UsernamePasswordAuthenticationToken(accountDto.getEmail(), accountDto.getPassword());
Authentication auth = authenticationManager.authenticate(authReq);
SecurityContext sc = SecurityContextHolder.getContext();
sc.setAuthentication(auth);
}
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论