# Spring Boot - Authentication demo with Passwordless.ID

This minimalistic repository shows how to use [Passwordless.ID](https://passwordless.id) to authenticate users.

> Demo source code: [https://github.com/passwordless-id/spring-boot-demo](https://github.com/passwordless-id/spring-boot-demo)

## Dependencies

Spring Boot already has everything needed built-in for OpenID authentication. Thanks to that, adding a single dependency is enough.

```xml
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-oauth2-client</artifactId>
</dependency>
```

Adding this dependency will also add `spring-security` which will "protect" the whole web application by requiring the user to be authenticated to access anything.

## OpenID configuration

First, in `resources/application.properties` (or ".yaml"), *Passwordless.ID* has to be declared as identity provider.

```plaintext
spring.security.oauth2.client.provider.passwordless.issuer-uri = https://api.passwordless.id
```

Then, also how to configure the authentication requests.

```plaintext
spring.security.oauth2.client.registration.passwordless.client-id = http://localhost:8080
spring.security.oauth2.client.registration.passwordless.scope = openid avatar email
```

The `client-id` **must be** the domain where the web application runs. As a security measure from Passwordless.ID, redirects to URLs outside your *client-id* domain will be denied. On the other hand, all redirect URLs within this domain will be allowed, without the need to register them beforehand. Also, `localhost` constitutes an exception: it is always allowed and does not require *https*.

The `scope` represents what you want to read from the user's profile and must be granted by the user. The scope `avatar` is a convinience scope specific to Passwordless.ID which encompasses the claims `nickname`, `picture` and `preferred_username`. It is more privacy oriented than the usual `profile` which contains the real name of the user and additional personal information.

## Getting the user

Spring will do all the heavy lifting, and inject the OpenID Connect `user` obtained from Passwordless.ID. It works out-of-the-box, without the need to add any code.

In our example, only a single controller is present the user information: `MyController.java`.

```java
import org.springframework.security.core.annotation.AuthenticationPrincipal;
import org.springframework.security.oauth2.core.oidc.OidcUserInfo;
import org.springframework.security.oauth2.core.oidc.user.OidcUser;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class MyController {

    @GetMapping("/")
    public OidcUserInfo getUserInfo(@AuthenticationPrincipal OidcUser user) {
        return user.getUserInfo();
    }
}
```

## Try it out

Run the program, then open http://localhost:8080 . It should directly redirect to Passwordless.ID in order to authenticate you. Once done, it will return to the original endpoint. It should display something like this:

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1687419401002/d6ed861e-a669-42aa-8258-2373f37f7b12.png align="center")

## Adjusting the security policies

By default, *all* endpoints are secured by Spring Security and require authentication beforehand.

Of course, it's possible to fine-tune which URLs require authentication, and which do not, as well as many other things. Explaining how Spring Security works and how it to configure every possible thing is beyond the scope of this minimalistic tutorial though. For a good starting point, I recommend checking out this tutorial about [Spring Security and OpenID](https://www.baeldung.com/spring-security-openid-connect).
