简体   繁体   中英

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. 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.

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

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

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.

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). For this, you should implement a custom authentication filter and put it before your UsernamePasswordAuthenticationFilter in the spring's security filter chain. From here , you can find all about implementing registration + login with JWT in SpringSecurity and Angular. If you follow all steps correctly, there wont be a problem.

Yes. You are correct spring security handles /login . Here is sample 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,

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 .

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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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