How does silhouette determine whether a request is authorized or not?


#1

I have this controller:

class SecurityController @Inject() (val messagesApi: MessagesApi,
                                   silhouette: Silhouette[DefaultEnv],
                                   userService: UserService,
                                   authInfoRepository: AuthInfoRepository,
                                   authTokenService: AuthTokenService,
                                   passwordHasherRegistry: PasswordHasherRegistry,
                                   mailerClient: MailerClient,
                                   configuration: Configuration,
                                   credentialsProvider: CredentialsProvider,
                                   clock: Clock)
  extends  Controller with I18nSupport  {

  def signUp = Action.async(parse.json) { implicit request =>
    request.body.validate[SignUpInfo].map { data =>
      val loginInfo = LoginInfo(CredentialsProvider.ID, data.email)
      userService.retrieve(loginInfo).flatMap {
        case Some(user) =>
          Future.successful(BadRequest(Json.obj("message" -> Messages("user.exists"))))
        case None =>
          val authInfo = passwordHasherRegistry.current.hash(data.password)
          val userContact = Contact("", data.phone, data.email, data.address)
          val userDetails = UserDetails(data.username, data.firstName, data.familyName, data.role, userContact, None)
          val user = User(UUID.randomUUID(), data.client, loginInfo, userDetails, false)
          for {
            user <- userService.save(user)
            authInfo <- authInfoRepository.add(loginInfo, authInfo)
            authToken <- authTokenService.create(user.userID)
          } yield {
            val url = routes.ActivateAccountController.activate(authToken.id).absoluteURL()
            silhouette.env.eventBus.publish(SignUpEvent(user, request))
            mailerClient.send(Email(
              subject = Messages("email.sign.up.subject"),
              from = Messages("email.from"),
              to = Seq(data.email),
              bodyText = Some(views.txt.emails.signUp(user, url).body),
              bodyHtml = Some(views.html.emails.signUp(user, url).body)
            ))
            Ok(Json.obj("message" -> Messages("sign.up.email.sent", data.email)))
          }
      }
    }.recoverTotal {
      case error => Future.successful(BadRequest(Json.obj("message" -> Messages("invalid.data"))))
    }
  }
}

It worked as expected, i.e., a new user was created in the mongodb collection, an email was sent to the user’s address. But then I removed all users from the collection and started the server afresh, and when I tried to register the same user again, the server returns an “unauthorized” error.

I am wondering how this could happen. The signup methods is just a plain Action, so there shouldn’t be any restrictions, right? How does silhouette actually determine whether a request is authorized or not?


#2

Never mind. This happened because I had a CSRF filter.