简体   繁体   English

如何将 angular 登录表单传递给 spring 安全性

[英]How to pass angular login form to spring security

I have a CRUD project and I'm attempting to implement an angular frontend, and want to know how to pass the login form to spring security correctly.我有一个 CRUD 项目,我正在尝试实现 angular 前端,并且想知道如何正确地将登录表单传递给 spring 安全性。 Currently the post request gets performed, but in the loadUserByUsername method the username is null and I think it has to do with how I'm trying to send the form.目前已执行发布请求,但在 loadUserByUsername 方法中,用户名是 null,我认为这与我尝试发送表单的方式有关。

Login form登录表单

<form #userForm="ngForm" (ngSubmit)="doLogin(userForm)">
 
  <div class="container">
    <div>
      <input type="text" name="username" id="username" ngModel placeholder="username">
      <br>
      <input type="text" name="password" id="password" ngModel placeholder="password">
    </div>
    <button class="btn btn-primary">Login</button>

  </div>
</form>

Login.component.ts登录组件.ts

export class LoginComponent implements OnInit {

  
  constructor(private service:RestapiService, private router:Router) { }

  ngOnInit(): void {
  }

  doLogin(form: NgForm) {
    this.service.login(form).subscribe(data=> {
      console.log("logged in")
    },
      error=>console.log("error"));
      
  
    this.router.navigate(["/"]);
  }
}

RestapiService.ts RestapiService.ts

export class RestapiService {

  constructor(private http: HttpClient) { }

  public login(user:NgForm) {
    const headers = new HttpHeaders().set('Content-Type', 'application/x-www-form-urlencoded');
    
    return this.http.post("http://localhost:8080/login", user.value, {headers: headers});
  } 

}

loadUserByUsername按用户名加载用户

@Override
    public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
        AppUser user = appUserRepository.findByUsername(username);
        Collection<SimpleGrantedAuthority> authorities = new ArrayList<>();
        authorities.add(new SimpleGrantedAuthority(user.getRole()));
        return new User(user.getUsername(), user.getPassword(), authorities);   
    }

I have no mapping in my controller class to /login as I assume spring security automatically allows post requests to the endpoint.我的 controller class 没有映射到 /login,因为我假设 spring 安全性自动允许向端点发送请求。

As you haven't provided your WebSecurityConfigurations class and the details of how you are making the securityContext, I think You can use JWT mechanism in your login process(if you haven't tried it yet).由于您尚未提供 WebSecurityConfigurations class 以及如何制作 securityContext 的详细信息,我认为您可以在登录过程中使用 JWT 机制(如果您还没有尝试过)。 For this, you should implement a custom authentication filter and put it before your UsernamePasswordAuthenticationFilter in the spring's security filter chain.为此,您应该实现自定义身份验证过滤器并将其放在 Spring 的安全过滤器链中的 UsernamePasswordAuthenticationFilter 之前。 From here , you can find all about implementing registration + login with JWT in SpringSecurity and Angular.这里,您可以找到有关在 SpringSecurity 和 Angular 中使用 JWT 实现注册+登录的所有信息。 If you follow all steps correctly, there wont be a problem.如果您正确执行所有步骤,则不会有问题。

Yes.是的。 You are correct spring security handles /login .您是正确的 spring 安全句柄/login Here is sample login.html这是登录示例login.html

<form ngNoForm action="/login" method="POST">
<p>
    User: <input name="username"/>
</p>
<p>
    Password: <input type="password" name="password"/>
</p>
<p>
<button type="submit">Sign In</button>
</p>
</form>

To get the authenticated user from spring security context, you can write something like this,要从 spring 安全上下文中获取经过身份验证的用户,您可以编写如下内容,

public User getAuthenticatedUser() {
    Authentication auth = SecurityContextHolder.getContext().getAuthentication();
    User user = null;
    if (null != auth && auth.isAuthenticated()) {
        Object principal = auth.getPrincipal();
        if (principal instanceof java.lang.String) {
            // anonymousUser
            user = new User();
            user.setUsername(principal.toString());
            user.setFirstName("anonymous");
            user.setLastName("anonymous");
            user.setId(UUID.randomUUID().toString());
        } else {
            user= (User) principal;
        }

        logger.trace("Found user " + user.getUsername());
        return user;
    }
    return user;
}

Here is a sample, AppUserDetailService.java .这是一个示例, AppUserDetailService.java

public class AppUserDetailService implements UserDetailsService {
    @Autowired
    private UserServices userServices;
    @Override
    public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
        User user = userServices.findByUsername(username);

        if (null == user) {
          //mainly used for junits
            if (null != username && username.equalsIgnoreCase("root")) {
              user = new User();
              user.setFirstName("root");
              user.setLastName("system");
              user.setUsername(username);
              user.setPricingTag(PricingTag.GOLD_TAG);
              return user;
            }
            throw new UsernameNotFoundException("could not find the user '"
                    + username + "'");
        }

        return user;
    }
}

In the above we assume, you created a custom User class that is specific to your application.在上面我们假设,您创建了一个特定于您的应用程序的自定义User class。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM