The boss of http auth.

Overview

Authboss

GoDoc ActionsCI Mail Go Coverage Go Report Card

Authboss is a modular authentication system for the web.

It has several modules that represent authentication and authorization features that are common to websites in general so that you can enable as many as you need, and leave the others out. It makes it easy to plug in authentication to an application and get a lot of functionality for (hopefully) a smaller amount of integration effort.

New to v2?

v1 -> v2 was a very big change. If you're looking to upgrade there is a general guide in tov2.md in this project.

New to v3?

v2 -> v3 was not a big change, it simply changed the project to use Go modules. Authboss no longer supports GOPATH as of version 3

Why use Authboss?

Every time you'd like to start a new web project, you really want to get to the heart of what you're trying to accomplish very quickly and it would be a sure bet to say one of the systems you're excited about implementing and innovating on is not authentication. In fact it's very much the opposite: it's one of those things that you have to do and one of those things you loathe to do. Authboss is supposed to remove a lot of the tedium that comes with this, as well as a lot of the chances to make mistakes. This allows you to care about what you're intending to do, rather than care about ancillary support systems required to make what you're intending to do happen.

Here are a few bullet point reasons you might like to try it out:

  • Saves you time (Authboss integration time should be less than re-implementation time)
  • Saves you mistakes (at least using Authboss, people can bug fix as a collective and all benefit)
  • Should integrate with or without any web framework

Click Here To Get Started

Readme Table of Contents

Getting Started

To get started with Authboss in the simplest way, is to simply create a Config, populate it with the things that are required, and start implementing use cases. The use cases describe what's required to be able to use a particular piece of functionality, or the best practice when implementing a piece of functionality. Please note the app requirements for your application as well integration requirements that follow.

Of course the standard practice of fetching the library is just the beginning:

# Get the latest, you must be using Go modules as of v3 of Authboss.
go get -u github.com/volatiletech/authboss/v3

Here's a bit of starter code that was stolen from the sample.

ab := authboss.New()

ab.Config.Storage.Server = myDatabaseImplementation
ab.Config.Storage.SessionState = mySessionImplementation
ab.Config.Storage.CookieState = myCookieImplementation

ab.Config.Paths.Mount = "/authboss"
ab.Config.Paths.RootURL = "https://www.example.com/"

// This is using the renderer from: github.com/volatiletech/authboss
ab.Config.Core.ViewRenderer = abrenderer.NewHTML("/auth", "ab_views")
// Probably want a MailRenderer here too.


// This instantiates and uses every default implementation
// in the Config.Core area that exist in the defaults package.
// Just a convenient helper if you don't want to do anything fancy.
 defaults.SetCore(&ab.Config, false, false)

if err := ab.Init(); err != nil {
    panic(err)
}

// Mount the router to a path (this should be the same as the Mount path above)
// mux in this example is a chi router, but it could be anything that can route to
// the Core.Router.
mux.Mount("/authboss", http.StripPrefix("/authboss", ab.Config.Core.Router))

For a more in-depth look you definitely should look at the authboss sample to see what a full implementation looks like. This will probably help you more than any of this documentation.

https://github.com/volatiletech/authboss-sample

App Requirements

Authboss does a lot of things, but it doesn't do some of the important things that are required by a typical authentication system, because it can't guarantee that you're doing many of those things in a different way already, so it punts the responsibility.

CSRF Protection

What this means is you should apply a middleware that can protect the application from csrf attacks or you may be vulnerable. Authboss previously handled this but it took on a dependency that was unnecessary and it complicated the code. Because Authboss does not render views nor consumes data directly from the user, it no longer does this.

Request Throttling

Currently Authboss is vulnerable to brute force attacks because there are no protections on it's endpoints. This again is left up to the creator of the website to protect the whole website at once (as well as Authboss) from these sorts of attacks.

Integration Requirements

In terms of integrating Authboss into your app, the following things must be considered.

Middleware

There are middlewares that are required to be installed in your middleware stack if it's all to function properly, please see Middlewares for more information.

Configuration

There are some required configuration variables that have no sane defaults and are particular to your app:

  • Config.Paths.Mount
  • Config.Paths.RootURL

Storage and Core implementations

Everything under Config.Storage and Config.Core are required and you must provide them, however you can optionally use default implementations from the defaults package. This also provides an easy way to share implementations of certain stack pieces (like HTML Form Parsing). As you saw in the example above these can be easily initialized with the SetCore method in that package.

The following is a list of storage interfaces, they must be provided by the implementer. Server is a very involved implementation, please see the additional documentation below for more details.

  • Config.Storage.Server
  • Config.Storage.SessionState
  • Config.Storage.CookieState (only for "remember me" functionality)

The following is a list of the core pieces, these typically are abstracting the HTTP stack. Out of all of these you'll probably be mostly okay with the default implementations in the defaults package but there are two big exceptions to this rule and that's the ViewRenderer and the MailRenderer. For more information please see the use case Rendering Views

  • Config.Core.Router
  • Config.Core.ErrorHandler
  • Config.Core.Responder
  • Config.Core.Redirector
  • Config.Core.BodyReader
  • Config.Core.ViewRenderer
  • Config.Core.MailRenderer
  • Config.Core.Mailer
  • Config.Core.Logger

ServerStorer implementation

The ServerStorer is meant to be upgraded to add capabilities depending on what modules you'd like to use. It starts out by only knowing how to save and load users, but the remember module as an example needs to be able to find users by remember me tokens, so it upgrades to a RememberingServerStorer which adds these abilities.

Your ServerStorer implementation does not need to implement all these additional interfaces unless you're using a module that requires it. See the Use Cases documentation to know what the requirements are.

User implementation

Users in Authboss are represented by the User interface. The user interface is a flexible notion, because it can be upgraded to suit the needs of the various modules.

Initially the User must only be able to Get/Set a PID or primary identifier. This allows the authboss modules to know how to refer to him in the database. The ServerStorer also makes use of this to save/load users.

As mentioned, it can be upgraded, for example suppose now we want to use the confirm module, in that case the e-mail address now becomes a requirement. So the confirm module will attempt to upgrade the user (and panic if it fails) to a ConfirmableUser which supports retrieving and setting of confirm tokens, e-mail addresses, and a confirmed state.

Your User implementation does not need to implement all these additional user interfaces unless you're using a module that requires it. See the Use Cases documentation to know what the requirements are.

Values implementation

The BodyReader interface in the Config returns Validator implementations which can be validated. But much like the storer and user it can be upgraded to add different capabilities.

A typical BodyReader (like the one in the defaults package) implementation checks the page being requested and switches on that to parse the body in whatever way (msgpack, json, url-encoded, doesn't matter), and produce a struct that has the ability to Validate() it's data as well as functions to retrieve the data necessary for the particular valuer required by the module.

An example of an upgraded Valuer is the UserValuer which stores and validates the PID and Password that a user has provided for the modules to use.

Your body reader implementation does not need to implement all valuer types unless you're using a module that requires it. See the Use Cases documentation to know what the requirements are.

Config

The config struct is an important part of Authboss. It's the key to making Authboss do what you want with the implementations you want. Please look at it's code definition as you read the documentation below, it will make much more sense.

Config Struct Documentation

Paths

Paths are the paths that should be redirected to or used in whatever circumstance they describe. Two special paths that are required are Mount and RootURL without which certain authboss modules will not function correctly. Most paths get defaulted to / such as after login success or when a user is locked out of their account.

Modules

Modules are module specific configuration options. They mostly control the behavior of modules. For example RegisterPreserveFields decides a whitelist of fields to allow back into the data to be re-rendered so the user doesn't have to type them in again.

Mail

Mail sending related options.

Storage

These are the implementations of how storage on the server and the client are done in your app. There are no default implementations for these at this time. See the Godoc for more information about what these are.

Core

These are the implementations of the HTTP stack for your app. How do responses render? How are they redirected? How are errors handled?

For most of these there are default implementations from the defaults package available, but not for all. See the package documentation for more information about what's available.

Available Modules

Each module can be turned on simply by importing it and the side-effects take care of the rest. Not all the capabilities of authboss are represented by a module, see Use Cases to view the supported use cases as well as how to use them in your app.

Note: The two factor packages do not enable via side-effect import, see their documentation for more information.

Name Import Path Description
Auth github.com/volatiletech/authboss/v3/auth Database password authentication for users.
Confirm github.com/volatiletech/authboss/v3/confirm Prevents login before e-mail verification.
Expire github.com/volatiletech/authboss/v3/expire Expires a user's login
Lock github.com/volatiletech/authboss/v3/lock Locks user accounts after authentication failures.
Logout github.com/volatiletech/authboss/v3/logout Destroys user sessions for auth/oauth2.
OAuth1 github.com/stephenafamo/authboss-oauth1 Provides oauth1 authentication for users.
OAuth2 github.com/volatiletech/authboss/v3/oauth2 Provides oauth2 authentication for users.
Recover github.com/volatiletech/authboss/v3/recover Allows for password resets via e-mail.
Register github.com/volatiletech/authboss/v3/register User-initiated account creation.
Remember github.com/volatiletech/authboss/v3/remember Persisting login sessions past session cookie expiry.
OTP github.com/volatiletech/authboss/v3/otp One time passwords for use instead of passwords.
Twofactor github.com/volatiletech/authboss/v3/otp/twofactor Regenerate recovery codes for 2fa.
Totp2fa github.com/volatiletech/authboss/v3/otp/twofactor/totp2fa Use Google authenticator-like things for a second auth factor.
Sms2fa github.com/volatiletech/authboss/v3/otp/twofactor/sms2fa Use a phone for a second auth factor.

Middlewares

The only middleware that's truly required is the LoadClientStateMiddleware, and that's because it enables session and cookie handling for Authboss. Without that, it's not a very useful piece of software.

The remaining middlewares are either the implementation of an entire module (like expire), or a key part of a module. For example you probably wouldn't want to use the lock module without the middleware that would stop a locked user from using an authenticated resource, because then locking wouldn't be useful unless of course you had your own way of dealing with locking, which is why it's only recommended, and not required. Typically you will use the middlewares if you use the module.

Name Requirement Description
Middleware Recommended Prevents unauthenticated users from accessing routes.
LoadClientStateMiddleware Required Enables cookie and session handling
ModuleListMiddleware Optional Inserts a loaded module list into the view data
confirm.Middleware Recommended with confirm Ensures users are confirmed or rejects request
expire.Middleware Required with expire Expires user sessions after an inactive period
lock.Middleware Recommended with lock Rejects requests from locked users
remember.Middleware Recommended with remember Logs a user in from a remember cookie

Use Cases

Get Current User

CurrentUser can be retrieved by calling Authboss.CurrentUser but a pre-requisite is that Authboss.LoadClientState has been called first to load the client state into the request context. This is typically achieved by using the Authboss.LoadClientStateMiddleware, but can be done manually as well.

Reset Password

Updating a user's password is non-trivial for several reasons:

  1. The bcrypt algorithm must have the correct cost, and also be being used.
  2. The user's remember me tokens should all be deleted so that previously authenticated sessions are invalid
  3. Optionally the user should be logged out (not taken care of by UpdatePassword)

In order to do this, we can use the Authboss.UpdatePassword method. This ensures the above facets are taken care of which the exception of the logging out part.

If it's also desirable to have the user logged out, please use the following methods to erase all known sessions and cookies from the user.

Note: DelKnownSession has been deprecated for security reasons

User Auth via Password

Info and Requirements
Module auth
Pages login
Routes /login
Emails None
Middlewares LoadClientStateMiddleware
ClientStorage Session and Cookie
ServerStorer ServerStorer
User AuthableUser
Values UserValuer
Mailer None

To enable this side-effect import the auth module, and ensure that the requirements above are met. It's very likely that you'd also want to enable the logout module in addition to this.

Direct a user to GET /login to have them enter their credentials and log in.

User Auth via OAuth1

Info and Requirements
Module oauth1
Pages None
Routes /oauth1/{provider}, /oauth1/callback/{provider}
Emails None
Middlewares LoadClientStateMiddleware
ClientStorage Session
ServerStorer OAuth1ServerStorer
User OAuth1User
Values None
Mailer None

This is a tougher implementation than most modules because there's a lot going on. In addition to the requirements stated above, you must also configure the oauth1.Providers. It's a public variable in the module.

import oauth1 "github.com/stephenafamo/authboss-oauth1"

oauth1.Providers = map[string]oauth1.Provider{}

The providers require an oauth1 configuration that's typical for the Go oauth1 package, but in addition to that they need a FindUserDetails method which has to take the token that's retrieved from the oauth1 provider, and call an endpoint that retrieves details about the user (at LEAST user's uid). These parameters are returned in map[string]string form and passed into the oauth1.ServerStorer.

Please see the following documentation for more details:

User Auth via OAuth2

Info and Requirements
Module oauth2
Pages None
Routes /oauth2/{provider}, /oauth2/callback/{provider}
Emails None
Middlewares LoadClientStateMiddleware
ClientStorage Session
ServerStorer OAuth2ServerStorer
User OAuth2User
Values None
Mailer None

This is a tougher implementation than most modules because there's a lot going on. In addition to the requirements stated above, you must also configure the OAuth2Providers in the config struct.

The providers require an oauth2 configuration that's typical for the Go oauth2 package, but in addition to that they need a FindUserDetails method which has to take the token that's retrieved from the oauth2 provider, and call an endpoint that retrieves details about the user (at LEAST user's uid). These parameters are returned in map[string]string form and passed into the OAuth2ServerStorer.

Please see the following documentation for more details:

User Registration

Info and Requirements
Module register
Pages register
Routes /register
Emails None
Middlewares LoadClientStateMiddleware
ClientStorage Session
ServerStorer CreatingServerStorer
User AuthableUser, optionally ArbitraryUser
Values UserValuer, optionally also ArbitraryValuer
Mailer None

Users can self-register for a service using this module. You may optionally want them to confirm themselves, which can be done using the confirm module.

The complicated part in implementing registrations are around the RegisterPreserveFields. This is to help in the case where a user fills out many fields, and then say enters a password which doesn't meet minimum requirements and it fails during validation. These preserve fields should stop the user from having to type in all that data again (it's a whitelist). This must be used in conjuction with ArbitraryValuer and although it's not a hard requirement ArbitraryUser should be used otherwise the arbitrary values cannot be stored in the database.

When the register module sees arbitrary data from an ArbitraryValuer, it sets the data key authboss.DataPreserve with a map[string]string in the data for when registration fails. This means the (whitelisted) values entered by the user previously will be accessible in the templates by using .preserve.field_name. Preserve may be empty or nil so use {{with ...}} to make sure you don't have template errors.

There is additional Godoc documentation on the RegisterPreserveFields config option as well as the ArbitraryUser and ArbitraryValuer interfaces themselves.

Confirming Registrations

Info and Requirements
Module confirm
Pages confirm
Routes /confirm
Emails confirm_html, confirm_txt
Middlewares LoadClientStateMiddleware, confirm.Middleware
ClientStorage Session
ServerStorer ConfirmingServerStorer
User ConfirmableUser
Values ConfirmValuer
Mailer Required

Confirming registrations via e-mail can be done with this module (whether or not done via the register module).

A hook on register kicks off the start of a confirmation which sends an e-mail with a token for the user. When the user re-visits the page, the BodyReader must read the token and return a type that returns the token.

Confirmations carry two values in the database to prevent a timing attack. The selector and the verifier, always make sure in the ConfirmingServerStorer you're searching by the selector and not the verifier.

Password Recovery

Info and Requirements
Module recover
Pages recover_start, recover_middle (not used for renders, only values), recover_end
Routes /recover, /recover/end
Emails recover_html, recover_txt
Middlewares LoadClientStateMiddleware
ClientStorage Session
ServerStorer RecoveringServerStorer
User RecoverableUser
Values RecoverStartValuer, RecoverMiddleValuer, RecoverEndValuer
Mailer Required

The flow for password recovery is that the user is initially shown a page that wants their PID to be entered. The RecoverStartValuer retrieves that on POST to /recover.

An e-mail is sent out, and the user clicks the link inside it and is taken back to /recover/end as a GET, at this point the RecoverMiddleValuer grabs the token and will insert it into the data to be rendered.

They enter their password into the form, and POST to /recover/end which sends the token and the new password which is retrieved by RecoverEndValuer which sets their password and saves them.

Password recovery has two values in the database to prevent a timing attack. The selector and the verifier, always make sure in the RecoveringServerStorer you're searching by the selector and not the verifier.

Remember Me

Info and Requirements
Module remember
Pages None
Routes None
Emails None
Middlewares LoadClientStateMiddleware,
Middlewares LoadClientStateMiddleware, remember.Middleware
ClientStorage Session, Cookies
ServerStorer RememberingServerStorer
User User
Values RememberValuer (not a Validator)
Mailer None

Remember uses cookie storage to log in users without a session via the remember.Middleware. Because of this this middleware should be used high up in the stack, but it also needs to be after the LoadClientStateMiddleware so that client state is available via the authboss mechanisms.

There is an intricacy to the RememberingServerStorer, it doesn't use the User struct at all, instead it simply instructs the storer to save tokens to a pid and recall them just the same. Typically in most databases this will require a separate table, though you could implement using pg arrays or something as well.

A user who is logged in via Remember tokens is also considered "half-authed" which is a session key (authboss.SessionHalfAuthKey) that you can query to check to see if a user should have full rights to more sensitive data, if they are half-authed and they want to change their user details for example you may want to force them to go to the login screen and put in their password to get a full auth first. The authboss.Middleware has a boolean flag to forceFullAuth which prevents half-authed users from using that route.

Locking Users

Info and Requirements
Module lock
Pages None
Routes None
Emails None
Middlewares LoadClientStateMiddleware, lock.Middleware
ClientStorage Session
ServerStorer ServerStorer
User LockableUser
Values None
Mailer None

Lock ensures that a user's account becomes locked if authentication (both auth, oauth2, otp) are failed enough times.

The middleware protects resources from locked users, without it, there is no point to this module. You should put in front of any resource that requires a login to function.

Expiring User Sessions

Info and Requirements
Module expire
Pages None
Routes None
Emails None
Middlewares LoadClientStateMiddleware, expire.Middleware
ClientStorage Session
ServerStorer None
User User
Values None
Mailer None

Note: Unlike most modules in Authboss you must call expire.Setup() to enable this module. See the sample to see how to do this. This may be changed in the future.

Expire simply uses sessions to track when the last action of a user is, if that action is longer than configured then the session is deleted and the user removed from the request context.

This middleware should be inserted at a high level (closer to the request) in the middleware chain to ensure that "activity" is logged properly, as well as any middlewares down the chain do not attempt to do anything with the user before it's removed from the request context.

One Time Passwords

Info and Requirements
Module otp
Pages otp, otpadd, otpclear
Routes /otp/login, /otp/add, /otp/clear
Emails None
Middlewares LoadClientStateMiddleware
ClientStorage Session and Cookie
ServerStorer ServerStorer
User otp.User
Values UserValuer
Mailer None

One time passwords can be useful if users require a backup password in case they lose theirs, or they're logging in on an untrusted computer. This module allows users to add one time passwords, clear them, or log in with them.

Logging in with a one time password instead of a password is identical to having logged in normally with their typical password with the exception that the one time passwords are consumed immediately upon use and cannot be used again.

otp should not be confused with two factor authentication. Although 2fa also uses one-time passwords the otp module has nothing to do with it and is strictly a mechanism for logging in with an alternative to a user's regular password.

Two Factor Authentication

2FA in Authboss is implemented in a few separate modules: twofactor, totp2fa and sms2fa.

You should use two factor authentication in your application if you want additional security beyond that of just simple passwords. Each 2fa module supports a different mechanism for verifying a second factor of authentication from a user.

Two-Factor Recovery

Info and Requirements
Module twofactor
Pages recovery2fa
Routes /2fa/recovery/regen
Emails None
Middlewares LoadClientStateMiddleware
ClientStorage Session
ServerStorer ServerStorer
User twofactor.User
Values None
Mailer None

Note: Unlike most modules in Authboss you must construct a twofactor.Recovery and call .Setup() on it to enable this module. See the sample to see how to do this. This may be changed in the future.

Package twofactor is all about the common functionality of providing backup codes for two factor mechanisms. Instead of each module implementing backup codes on it's own, common functionality has been put here including a route to regenerate backup codes.

Backup codes are useful in case people lose access to their second factor for authentication. This happens when users lose their phones for example. When this occurs, they can use one of their backup-codes.

Backup codes are one-time use, they are bcrypted for security, and they only allow bypassing the 2fa authentication part, they cannot be used in lieu of a user's password, for that sort of recovery see the otp module.

Two-Factor Setup E-mail Authorization

Info and Requirements
Module twofactor
Pages twofactor_verify
Routes /2fa/recovery/regen
Emails twofactor_verify_email_html, twofactor_verify_email_txt
Middlewares LoadClientStateMiddleware
ClientStorage Session
ServerStorer ServerStorer
User twofactor.User
Values twofactor.EmailVerifyTokenValuer
Mailer Required

To enable this feature simply turn on authboss.Config.Modules.TwoFactorEmailAuthRequired and new routes and middlewares will be installed when you set up one of the 2fa modules.

When enabled, the routes for setting up 2fa on an account are protected by a middleware that will redirect to /2fa/{totp,sms}/email/verify where Page twofactor_verify is displayed. The user is prompted to authorize the addition of 2fa to their account. The data for this page contains email and a url for the POST. The url is required because this page is shared between all 2fa types.

Once they POST to the url, a token is stored in their session and an e-mail is sent with that token. When they click the link that goes to /2fa/{totp,sms}/email/verify/end with a token in the query string the session token is verified and exchanged for a value that says they're verified and lastly it redirects them to the setup URL for the type of 2fa they were attempting to setup.

Time-Based One Time Passwords 2FA (totp)

Info and Requirements
Module totp2fa
Pages totp2fa_{setup,confirm,remove,validate}, totp2fa_{confirm,remove}_success
Routes /2fa/totp/{setup,confirm,qr,remove,validate}
Emails None
Middlewares LoadClientStateMiddleware
ClientStorage Session (SECURE!)
ServerStorer ServerStorer
User totp2fa.User
Values TOTPCodeValuer
Mailer None

Note: Unlike most modules in Authboss you must construct a totp2fa.TOTP and call .Setup() on it to enable this module. See the sample to see how to do this This may be changed in the future.

Note: To allow users to regenerate their backup codes, you must also use the twofactor module.

Note: Routes are protected by authboss.Middleware so only logged in users can access them. You can configure whether unauthenticated users should be redirected to log in or are 404'd using the authboss.Config.Modules.RoutesRedirectOnUnathed configuration flag.

Adding 2fa to a user

When a logged in user would like to add 2fa to their account direct them GET /2fa/totp/setup, the GET on this page does virtually nothing so you don't have to use it, just POST immediately to have a smoother flow for the user. This puts the 2fa secret in their session temporarily meaning you must have proper secure sessions for this to be secure.

They will be redirected to GET /2fa/totp/confirm where the data will show totp2fa.DataTOTPSecret, this is the key that user's should enter into their Google Authenticator or similar app. Once they've added it they need to send a POST /2fa/totp/confirm with a correct code which removes the 2fa secret from their session and permanently adds it to their totp2fa.User and 2fa is now enabled for them. The data from the POST will contain a key twofactor.DataRecoveryCodes that contains an array of recovery codes for the user.

If you wish to show the user a QR code, GET /2fa/totp/qr at any time during or after totp2fa setup will return a 200x200 png QR code that they can scan.

Removing 2fa from a user

A user begins by going to GET /2fa/totp/remove and enters a code which posts to POST /2fa/totp/remove and if it's correct they're shown a success page and 2fa is removed from them, if not they get validation errors.

Logging in with 2fa

When a user goes to log in, the totp module checks the user after they log in for the presence of a totp2fa secret, if there is one it does not give them a logged in session value immediately and redirects them to GET /2fa/totp/validate where they must enter a correct code to POST /2fa/totp/validate if the code is correct they're logged in normally as well as they get the session value authboss.Session2FA set to "totp" to prove that they've authenticated with two factors.

Using Recovery Codes

Both when logging in and removing totp2fa from an account, a recovery code may be used instead. They can POST to the same url, they simply send a different form field. The recovery code is consumed on use and may not be used again.

Text Message 2FA (sms)

Package sms2fa uses sms shared secrets as a means to authenticate a user with a second factor: their phone number.

Info and Requirements
Module sms2fa
Pages sms2fa_{setup,confirm,remove,validate}, sms2fa_{confirm,remove}_success
Routes /2fa/{setup,confirm,remove,validate}
Emails None
Middlewares LoadClientStateMiddleware
ClientStorage Session (SECURE!)
ServerStorer ServerStorer
User sms2fa.User, sms2fa.SMSNumberProvider
Values SMSValuer, SMSPhoneNumberValuer
Mailer None

Note: Unlike most modules in Authboss you must construct a sms2fa.SMS and call .Setup() on it to enable this module. See the sample to see how to do this. This may be changed in the future.

Note: To allow users to regenerate their backup codes, you must also use the twofactor module.

Note: Routes are protected by authboss.Middleware so only logged in users can access them. You can configure whether unauthenticated users should be redirected to log in or are 404'd using the authboss.Config.Modules.RoutesRedirectOnUnathed configuration flag.

Note: sms2fa always stores the code it's expecting in the user's session therefore you must have secure sessions or the code itself is not secure!

Note: sms2fa pages all send codes via sms on POST when no data code is given. This is also how users can resend the code in case they did not get it (for example a second POST /2fa/sms/{confirm,remove} with no form-fields filled in will end up resending the code).

Note: Sending sms codes is rate-limited to 1 sms/10 sec for that user, this is controlled by placing a timestamp in their session to prevent abuse.

Adding 2fa to a user

When a logged in user would like to add 2fa to their account direct them GET /2fa/sms/setup where they must enter a phone number. If the logged in user also implements sms2fa.SMSNumberProvider then this interface will be used to retrieve a phone number (if it exists) from the user and put it in sms2fa.DataSMSPhoneNumber so that the user interface can populate it for the user, making it convenient to re-use an already saved phone number inside the user.

Once they POST /2fa/sms/setup with a phone number, the sms2fa.Sender interface will be invoked to send the SMS code to the user and they will be redirected to GET /2fa/sms/confirm where they enter the code they received which does a POST /2fa/sms/confirm to store the phone number they were confirming permanently on their user using sms2fa.User which enables sms2fa for them. The data from the POST will contain a key twofactor.DataRecoveryCodes that contains an array of recovery codes for the user.

Removing 2fa from a user

A user begins by going to GET /2fa/sms/remove. This page does nothing on it's own. In order to begin the process POST /2fa/sms/remove with no data (or a recovery code to skip needing the sms code) to send the sms code to the user. Then they can POST /2fa/sms/remove again with the correct code to have it permanently removed.

Logging in with 2fa

When a user goes to log in, the sms module checks the user after they log in for the presence of a sms2fa phone number, if there is one it does not give them a logged in session value but instead sends an SMS code to their configured number and and redirects them to GET /2fa/sms/validate where they must enter a correct code to POST /2fa/totp/validate. If the code is correct they're logged in normally as well as they get the session value authboss.Session2FA set to "sms" to prove that they've authenticated with two factors.

Using Recovery Codes

Same as totp2fa above.

Rendering Views

The authboss rendering system is simple. It's defined by one interface: Renderer

The renderer knows how to load templates, and how to render them with some data and that's it. So let's examine the most common view types that you might want to use.

HTML Views

When your app is a traditional web application and is generating it's HTML serverside using templates this becomes a small wrapper on top of your rendering setup. For example if you're using html/template then you could just use template.New() inside the Load() method and store that somewhere and call template.Execute() in the Render() method.

There is also a very basic renderer: Authboss Renderer which has some very ugly built in views and the ability to override them with your own if you don't want to integrate your own rendering system into that interface.

JSON Views

If you're building an API that's mostly backed by a javascript front-end, then you'll probably want to use a renderer that converts the data to JSON. There is a simple json renderer available in the defaults package package if you wish to use that.

Data

The most important part about this interface is the data that you have to render. There are several keys that are used throughout authboss that you'll want to render in your views.

They're in the file html_data.go and are constants prefixed with Data. See the documentation in that file for more information on which keys exist and what they contain.

The default responder also happens to collect data from the Request context, and hence this is a great place to inject data you'd like to render (for example data for your html layout, or csrf tokens).

Issues
  • Additional -Maker properties on Config for GAE support

    Additional -Maker properties on Config for GAE support

    I tried to keep everything about these new properties as consistent with CookieStoreMaker/SessionStoreMaker as I could. However, I may very well have structured this in such a way that the new -Maker functions won't always have been called by the time they're needed to have been called. I didn't do any testing or thorough investigation beyond some greps to make sure that my change wasn't obviously wrong, as I figure that with your better grasp on the broader structure and context of the code, issues of that nature will be more immediately apparent to you when you review this.

    opened by buu700 13
  • patch bug in OAuth2 module

    patch bug in OAuth2 module

    In the OAuth2 module, the session PID is put like this:

    authboss.PutSession(w, authboss.SessionKey, authboss.MakeOAuth2PID(provider, user.GetOAuth2UID()))
    

    I don't think it's necessary. Since the OAuth2User interface already requires a GetPID method, I think we should use that directly and leave it up to the user to create the PID using the Helper function.

    This could also cause an issue because Middleware2 requires authboss.SessionKey to be the user PID, and during this process, theGetPID method is called. If the user themselves are not using authboss.MakeOAuth2PID to create their PIDs, they will run into a problem because the End method in the OAuth2 modules assumes this must be the case.

    I've also modified the mocks package to take this into account. So it does not return the email when the Oauth2 module tests ask for the PID.

    opened by stephenafamo 11
  • Revamping Authboss!!!

    Revamping Authboss!!!

    Unfortunately, when new users come to this repository, the cannot see how amazing it is due to lack of documentation and content. This needs to change. I forked the repo and made major experimental edits. Here is a list of the changes I made that I think would greatly improve the way the community sees this project. I can create pull requests for the ones that you approve of.

    • [ ] I created 3 generators using cobra. Running: authboss generate:templates ./destination authboss generate:user ./destination authboss generate:config ./destination Will generate the corresponding file/folder in the directory specified. These are located in internal/generators. These act just like devise generators, and are very useful. This requires moving the templates into the master repo, which I think should be done no matter what. I will add simple bootstrap css as well soon.
    • [ ] Improve the docs!!! You can view the beautiful docs site I created with docsify. They are very simple markdown pages, and deployed with github pages in the /docs directory
    • [ ] Convert expire to use side effects. This makes the whole project consistent, and was done in this commit
    • [ ] Simplify the sample application, make it actually compile, and put it in /examples. I am currently fixing some bugs, but this will be done soon.
    • [ ] Create a default html renderer. The abrenderer repo was quite overcomplicated. My implementation is a very simple file and very crucial for new users. This file is well tested, and accepts an optional layout template. It works for the view renderer and mail renderer.
    • [ ] Merge the authboss-clientstate into the main repo. This is CRUCIAL. It is only 2 files, and helps make the repo more appealing to users. The two added dependencies are part of the gorilla toolkit and very well maintained.

    Please accept this request. I want authboss to be the devise of golang. But to accomplish that, we must have documentation, resources, content, defaults everything, except the server store, and generators.

    To view all the updates I made, you can view my repo

    opened by ibraheemdev 9
  • make v2 the default branch

    make v2 the default branch

    It's very confusing that the default view of the code is the deprecated version. There's an option in github to make a branch the default view (rather than master). Could you do that, so that when people come here, they don't get confused?

    opened by natefinch 9
  • User is logged in after confirming his account

    User is logged in after confirming his account

    Hey @aarondl isn't it a security flaw? let's look at the following user case:

    1. User registers on an application
    2. User receives a confirmation email
    3. Someone accesses the user email
    4. Someone sees that the user has an account on that application and clicks on confirm
    5. This person now can do whatever he wants

    Is there any reason to make it this way? I just saw that on the confirmation process a session is created

    ctx.SessionStorer.Put(authboss.SessionKey, key)
    

    Should it really be happening?

    opened by kaiomagalhaes 9
  • Implement shallow remember me

    Implement shallow remember me

    Issue opened for the creation of a wiki page that summarizes the doubts and problems for newbies (https://github.com/volatiletech/authboss/issues/210).

    It would be amazing to use "Remember me" feature not with DB token queries, just using the cookie MaxAge > 0 if checkbox checked (like Rails devise gem does).

    Is there a way to do:

    if remember_me checkobx checked then cookie MaxAge = 30 days
    else MaxAge = 0
    

    Maybe I'm wrong about this because maybe I did not understand how authboss remember_me module works. In that case I will create a wiki page to explain this to newbies like me.

    opened by frederikhors 8
  • panic: ResponseWriter must be a ClientStateResponseWriter or UnderlyingResponseWriter

    panic: ResponseWriter must be a ClientStateResponseWriter or UnderlyingResponseWriter

    Hello!

    I released example project based on authboss. After login I got panic:

    2019-10-07T12:17:01.026Z	INFO	middleware/zap_logger.go:28	GET /auth/login	{"ip": "172.18.0.1", "ua": "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.90 Safari/537.36", "proto": "HTTP/1.1", "path": "/auth/login", "lat": "1.112036ms", "status": 200, "size": 456}
    camforchat-signal_1     | 2019-10-07T12:17:09Z [INFO]: user [email protected] is confirmed, allowing auth
    camforchat-signal_1     | 2019-10-07T12:17:09Z [INFO]: user [email protected] logged in
    camforchat-signal_1     | Panic: ResponseWriter must be a ClientStateResponseWriter or UnderlyingResponseWriter in (see: authboss.LoadClientStateMiddleware): *middleware.basicWriter
    camforchat-signal_1     | goroutine 38 [running]:
    camforchat-signal_1     | runtime/debug.Stack(0x9c, 0x0, 0x0)
    camforchat-signal_1     | 	/usr/local/go/src/runtime/debug/stack.go:24 +0x9d
    camforchat-signal_1     | runtime/debug.PrintStack()
    camforchat-signal_1     | 	/usr/local/go/src/runtime/debug/stack.go:16 +0x22
    camforchat-signal_1     | github.com/go-chi/chi/middleware.Recoverer.func1.1(0xc000261b00, 0x7f30b1a4d168, 0xc000121440)
    camforchat-signal_1     | 	/go/pkg/mod/github.com/go-chi/[email protected]+incompatible/middleware/recoverer.go:28 +0x1b7
    camforchat-signal_1     | panic(0x8a9d00, 0xc00013b370)
    camforchat-signal_1     | 	/usr/local/go/src/runtime/panic.go:522 +0x1b5
    camforchat-signal_1     | github.com/volatiletech/authboss.MustClientStateResponseWriter(0x7f30b1a4d168, 0xc000121440, 0xc0000fe840)
    camforchat-signal_1     | 	/go/pkg/mod/github.com/volatiletech/[email protected]+incompatible/client_state.go:188 +0x12e
    camforchat-signal_1     | github.com/volatiletech/authboss.setState(0x7f30b1a4d168, 0xc000121440, 0x96a6d3, 0x7, 0x0, 0x967021, 0x3, 0xc00010a9a0, 0x11)
    camforchat-signal_1     | 	/go/pkg/mod/github.com/volatiletech/[email protected]+incompatible/client_state.go:344 +0x3f
    camforchat-signal_1     | github.com/volatiletech/authboss.putState(...)
    camforchat-signal_1     | 	/go/pkg/mod/github.com/volatiletech/[email protected]+incompatible/client_state.go:332
    camforchat-signal_1     | github.com/volatiletech/authboss.PutSession(...)
    camforchat-signal_1     | 	/go/pkg/mod/github.com/volatiletech/[email protected]+incompatible/client_state.go:303
    camforchat-signal_1     | github.com/volatiletech/authboss/auth.(*Auth).LoginPost(0xc00000e680, 0x7f30b1a4d168, 0xc000121440, 0xc000261d00, 0x0, 0xc00028b1d8)
    camforchat-signal_1     | 	/go/pkg/mod/github.com/volatiletech/[email protected]+incompatible/auth/auth.go:111 +0x76c
    camforchat-signal_1     | github.com/volatiletech/authboss/defaults.errorHandler.ServeHTTP(0xc00013a710, 0xa1ef00, 0xc0000fe7d0, 0x7f30b1a4d168, 0xc000121440, 0xc000261d00)
    camforchat-signal_1     | 	/go/pkg/mod/github.com/volatiletech/[email protected]+incompatible/defaults/error_handler.go:39 +0x62
    camforchat-signal_1     | net/http.(*ServeMux).ServeHTTP(0xc0000f8940, 0x7f30b1a4d168, 0xc000121440, 0xc000261d00)
    camforchat-signal_1     | 	/usr/local/go/src/net/http/server.go:2375 +0x1d6
    camforchat-signal_1     | github.com/volatiletech/authboss/defaults.(*Router).ServeHTTP(0xc0001049e0, 0x7f30b1a4d168, 0xc000121440, 0xc000261d00)
    camforchat-signal_1     | 	/go/pkg/mod/github.com/volatiletech/[email protected]+incompatible/defaults/router.go:64 +0x77
    camforchat-signal_1     | net/http.StripPrefix.func1(0x7f30b1a4d168, 0xc000121440, 0xc000261c00)
    camforchat-signal_1     | 	/usr/local/go/src/net/http/server.go:2034 +0x18d
    camforchat-signal_1     | net/http.HandlerFunc.ServeHTTP(0xc0001fb860, 0x7f30b1a4d168, 0xc000121440, 0xc000261c00)
    camforchat-signal_1     | 	/usr/local/go/src/net/http/server.go:1995 +0x44
    camforchat-signal_1     | github.com/go-chi/chi.(*Mux).Mount.func1(0x7f30b1a4d168, 0xc000121440, 0xc000261c00)
    camforchat-signal_1     | 	/go/pkg/mod/github.com/go-chi/[email protected]+incompatible/mux.go:292 +0x127
    camforchat-signal_1     | net/http.HandlerFunc.ServeHTTP(0xc00000d800, 0x7f30b1a4d168, 0xc000121440, 0xc000261c00)
    camforchat-signal_1     | 	/usr/local/go/src/net/http/server.go:1995 +0x44
    camforchat-signal_1     | github.com/volatiletech/authboss.ModuleListMiddleware.func1.1(0x7f30b1a4d168, 0xc000121440, 0xc000261b00)
    camforchat-signal_1     | 	/go/pkg/mod/github.com/volatiletech/[email protected]+incompatible/module.go:123 +0x400
    camforchat-signal_1     | net/http.HandlerFunc.ServeHTTP(0xc00000d8c0, 0x7f30b1a4d168, 0xc000121440, 0xc000261b00)
    camforchat-signal_1     | 	/usr/local/go/src/net/http/server.go:1995 +0x44
    camforchat-signal_1     | github.com/go-chi/chi.(*ChainHandler).ServeHTTP(0xc0001e5280, 0x7f30b1a4d168, 0xc000121440, 0xc000261b00)
    camforchat-signal_1     | 	/go/pkg/mod/github.com/go-chi/[email protected]+incompatible/chain.go:31 +0x52
    camforchat-signal_1     | github.com/go-chi/chi.(*Mux).routeHTTP(0xc000061800, 0x7f30b1a4d168, 0xc000121440, 0xc000261b00)
    camforchat-signal_1     | 	/go/pkg/mod/github.com/go-chi/[email protected]+incompatible/mux.go:425 +0x27f
    camforchat-signal_1     | net/http.HandlerFunc.ServeHTTP(0xc00013a850, 0x7f30b1a4d168, 0xc000121440, 0xc000261b00)
    camforchat-signal_1     | 	/usr/local/go/src/net/http/server.go:1995 +0x44
    camforchat-signal_1     | github.com/go-chi/chi/middleware.Recoverer.func1(0x7f30b1a4d168, 0xc000121440, 0xc000261b00)
    camforchat-signal_1     | 	/go/pkg/mod/github.com/go-chi/[email protected]+incompatible/middleware/recoverer.go:35 +0x9f
    camforchat-signal_1     | net/http.HandlerFunc.ServeHTTP(0xc00000d700, 0x7f30b1a4d168, 0xc000121440, 0xc000261b00)
    camforchat-signal_1     | 	/usr/local/go/src/net/http/server.go:1995 +0x44
    camforchat-signal_1     | gitlab.com/camforchat/server/middleware.CurrentUserDataInject.func1.1(0xa225c0, 0xc0002703f0, 0xc000261b00)
    camforchat-signal_1     | 	/app/middleware/current_user_data_inject.go:19 +0x309
    camforchat-signal_1     | net/http.HandlerFunc.ServeHTTP(0xc00000d720, 0xa225c0, 0xc0002703f0, 0xc000261800)
    camforchat-signal_1     | 	/usr/local/go/src/net/http/server.go:1995 +0x44
    camforchat-signal_1     | github.com/volatiletech/authboss.(*Authboss).LoadClientStateMiddleware.func1(0x7f30b1869188, 0xc000121100, 0xc000261600)
    camforchat-signal_1     | 	/go/pkg/mod/github.com/volatiletech/[email protected]+incompatible/client_state.go:135 +0x1fa
    camforchat-signal_1     | net/http.HandlerFunc.ServeHTTP(0xc00000d740, 0x7f30b1869188, 0xc000121100, 0xc000261600)
    camforchat-signal_1     | 	/usr/local/go/src/net/http/server.go:1995 +0x44
    camforchat-signal_1     | gitlab.com/camforchat/server/middleware.Db.func1.1(0x7f30b1869188, 0xc000121080, 0xc000261500)
    camforchat-signal_1     | 	/app/middleware/db.go:30 +0x2fb
    camforchat-signal_1     | net/http.HandlerFunc.ServeHTTP(0xc00000d760, 0x7f30b1869188, 0xc000121080, 0xc000261500)
    camforchat-signal_1     | 	/usr/local/go/src/net/http/server.go:1995 +0x44
    camforchat-signal_1     | gitlab.com/camforchat/server/middleware.ZapLogger.func1.1(0xa22900, 0xc0002721c0, 0xc000261500)
    camforchat-signal_1     | 	/app/middleware/zap_logger.go:40 +0x3ab
    camforchat-signal_1     | net/http.HandlerFunc.ServeHTTP(0xc00000d780, 0xa22900, 0xc0002721c0, 0xc000261400)
    camforchat-signal_1     | 	/usr/local/go/src/net/http/server.go:1995 +0x44
    camforchat-signal_1     | github.com/go-chi/chi/middleware.RealIP.func1(0xa22900, 0xc0002721c0, 0xc000261400)
    camforchat-signal_1     | 	/go/pkg/mod/github.com/go-chi/[email protected]+incompatible/middleware/realip.go:34 +0x99
    camforchat-signal_1     | net/http.HandlerFunc.ServeHTTP(0xc00000d7a0, 0xa22900, 0xc0002721c0, 0xc000261400)
    camforchat-signal_1     | 	/usr/local/go/src/net/http/server.go:1995 +0x44
    camforchat-signal_1     | github.com/go-chi/chi.(*Mux).ServeHTTP(0xc000061800, 0xa22900, 0xc0002721c0, 0xc000261300)
    camforchat-signal_1     | 	/go/pkg/mod/github.com/go-chi/[email protected]+incompatible/mux.go:82 +0x294
    camforchat-signal_1     | github.com/go-chi/chi.ServerBaseContext.func1(0xa22900, 0xc0002721c0, 0xc000261200)
    camforchat-signal_1     | 	/go/pkg/mod/github.com/go-chi/[email protected]+incompatible/context.go:147 +0x257
    camforchat-signal_1     | net/http.HandlerFunc.ServeHTTP(0xc0001fb980, 0xa22900, 0xc0002721c0, 0xc000261200)
    camforchat-signal_1     | 	/usr/local/go/src/net/http/server.go:1995 +0x44
    camforchat-signal_1     | net/http.serverHandler.ServeHTTP(0xc0001172b0, 0xa22900, 0xc0002721c0, 0xc000261200)
    camforchat-signal_1     | 	/usr/local/go/src/net/http/server.go:2774 +0xa8
    camforchat-signal_1     | net/http.(*conn).serve(0xc0002921e0, 0xa23680, 0xc000120ec0)
    camforchat-signal_1     | 	/usr/local/go/src/net/http/server.go:1878 +0x851
    camforchat-signal_1     | created by net/http.(*Server).Serve
    camforchat-signal_1     | 	/usr/local/go/src/net/http/server.go:2884 +0x2f4
    camforchat-signal_1     | 2019-10-07T12:17:09.830Z	INFO	middleware/zap_logger.go:28	POST /auth/login	{"ip": "172.18.0.1", "ua": "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.90 Safari/537.36", "proto": "HTTP/1.1", "path": "/auth/login", "lat": "80.964928ms", "status": 500, "size": 22}
    

    Here is cite from my code:

    r := chi.NewRouter()                                                                                                   
        r.Use(                                                                                                                 
            middleware.RealIP,                                                                                                 
            appMiddleware.ZapLogger(logger),                                                                                   
            appMiddleware.Db(dbConn),                                                                                          
            ab.LoadClientStateMiddleware,                                                                                      
            appMiddleware.CurrentUserDataInject(ab),                                                                           
            middleware.Recoverer,                                                                                              
        )                                                                                                                      
        r.Group(func(r chi.Router) {                                                                                           
            r.Use(authboss.Middleware2(ab, authboss.RequireNone, authboss.RespondUnauthorized), confirm.Middleware(ab))        
            r.Post("/sdp", func(w http.ResponseWriter, r *http.Request) {                                                      
            })                                                                                                                 
        })                                                                                                                     
                                                                                                                               
        r.Group(func(r chi.Router) {                                                                                           
            r.Use(authboss.ModuleListMiddleware(ab))                                                                           
            r.Mount("/auth", http.StripPrefix("/auth", ab.Config.Core.Router))                                                 
        })                                                                                                                     
                                                                                                                               
        r.Get("/", impl.HomePage)
    

    As you see, I used chi for router and I put ab.LoadClientStateMiddleware into middleware stack as required. But I got panic.

    opened by isqad 7
  • Use Authboss with GraphQL only

    Use Authboss with GraphQL only

    Hi, i am currently developing a Client/Server application with a web frontend. Communication between backend and frontend is handled via a GraphQL API.

    This library looks very promising and i am wondering if it is possible to use authboss only with an GraphQL api (e.g. login/signup/logout mutations, currentUser query)

    I've seen that there are json/html renderer, are they mandatory? Is the router required by authboss as well or can I extract the required data and respond via the api to the web frontend?

    I don't want a mix of REST and GraphQL endpoints, therefore I try to keep it GraphQL only.

    Thanks!

    opened by Pokerkoffer 7
  • Authboss and GoBuffalo integration almost done. Just some troubles. Any hint?

    Authboss and GoBuffalo integration almost done. Just some troubles. Any hint?

    GoBuffalo author markbates told me (https://github.com/volatiletech/authboss/issues/163) that he does not use authboss and so for now he can not spend time integrating it with buffalo.

    I'm opening this in case @aarondl or someone else can understand in a moment what is wrong with this: https://github.com/frederikhors/buffalo-authboss-sample

    Stackoverflow question: https://stackoverflow.com/questions/53742344/gobuffalo-and-authboss-authentication-system-integration

    I think I'm almost there, just something wrong, I don't understand what.

    opened by frederikhors 7
  • Confirm to access registration

    Confirm to access registration

    TL;DR Is it possible to create a confirm-to-register type of new user flow using Authboss?

    To elaborate slightly, what we're looking to do is:

    1. Collect email address
    2. Generate single-use confirmation token to deliver to email collected in step 1.
    3. Collect more information post-confirmation
    4. Create new user account

    I'm new to both Golang and Authboss and couldn't immediately figure out how to accomplish this without implementing it ourselves. If we indeed need to implement this ourselves, as Authboss already has facilities for generating Confirmation tokens and sending email, can we hook into those somehow?

    opened by nikcorg 7
  • [question] compatible with Buffalo

    [question] compatible with Buffalo

    Hi! I’ve played with https://github.com/gobuffalo/buffalo and wondering about compatibility with authboss. Authboss uses different renderer compare with plask (in buffalo). Also buffalo has own CSRF middleware which puts token automatically.

    Sorry if my question seems weirdly, I’m newby in Golang web.

    opened by danikarik 7
  • How to do a retry confirmation email ?

    How to do a retry confirmation email ?

    Hey there,

    I was playing around with authboss as a whole. Confirmation module works as expected. But out of curiosity wanted to try how to do a retry for confirmation mail to be sent again. Like scenarios in which user may have missed it etc.

    I found out that code its added as register event effect. But read in documentation that i can be triggered with register hook.

    Can someone please help me on, whether this is something achievable. I saw the function for it to start the flow but can't seem to get an idea on how to execute it.

    opened by akhilmhdh 0
  • Events ability to halt

    Events ability to halt

    Problem:

    We can't halt event loop from an event inside (stop other hooks to be executed)

    Fixes #337

    Idea of solution is to return a custom ErrHalt that will be considered to stop immediately the loop

    opened by larrycinnabar 0
  • Add ability to stop EventLoop from inside an event

    Add ability to stop EventLoop from inside an event

    What about an option to stop (Halt) event loop from inside an event? return true, nil will still loop through all registered hooks in the given event chain, and there is no option to stop and do not continue to following registered hooks

    opened by larrycinnabar 0
  • Feature/configurable hashing and encoding

    Feature/configurable hashing and encoding

    Problem

    Password hashing :hash:

    Password hashing process is hard-coded and can't be modified in any kind. There are cases where we do need control on how password is hashed:

    • Current flow is that user is fetched and then password is checked. But we don't want DB to return user at all, until we are 100% password is right. So we need to first, hash password and query by matching hashed passwords.
    • Other simple example is that application may have some requirements on hashing algorithms.

    Confirming/Recovering tokens :envelope:

    Reasons for unhardcoding this part:

    • For easier and better testing we need ability to mock token, selector, verifier
    • We need tokens to look shorter/prettier for some reason

    Problematic part :red_circle: :

    authboss.go has a public helper function VerifyPassword, that now works only if we use default Hasher. a todo item is left there in comments, explaining the issue

    Fixes #319, #288

    opened by larrycinnabar 0
  • How to resolve this error ? with echo v4

    How to resolve this error ? with echo v4

    echo: http: panic serving 127.0.0.1:55619: ResponseWriter must be a ClientStateResponseWriter or UnderlyingResponseWriter in (see: authboss.LoadClientStateMiddleware): *echo.Response

    opened by p000ic 1
  • OpenID Connect (oidc) support

    OpenID Connect (oidc) support

    OpenID Connect seems like an easier way to offer login than oauth2.

    If you think that this is a good idea, I could try to add it as a subpackage github.com/volatiletech/authboss/v3/oauth2/oidc.

    Here is my current implementation (based on https://github.com/caos/oidc):

    package oidc
    
    import (
    	"context"
    	"fmt"
    	"net/http"
    	"time"
    
    	"github.com/caos/oidc/pkg/client"
    	httphelper "github.com/caos/oidc/pkg/http"
    	caosoidc "github.com/caos/oidc/pkg/oidc"
    	"github.com/volatiletech/authboss/v3"
    	aboauth2 "github.com/volatiletech/authboss/v3/oauth2"
    	"golang.org/x/oauth2"
    )
    
    // NewProvider discovers the configuration of the OpenID Connect provider, based on issuer.
    func NewProvider(issuer, clientID, clientSecret string, scopes []string) (authboss.OAuth2Provider, error) {
    	cfg := &oauth2.Config{
    		ClientID:     clientID,
    		ClientSecret: clientSecret,
    		RedirectURL:  "", // will be filled later during init
    		Scopes:       scopes,
    	}
    	httpClient := &http.Client{
    		Timeout: 30 * time.Second,
    	}
    
    	dicovered, err := client.Discover(issuer, httpClient)
    	if err != nil {
    		return authboss.OAuth2Provider{}, err
    	}
    	cfg.Endpoint = oauth2.Endpoint{
    		AuthURL:   dicovered.AuthorizationEndpoint,
    		TokenURL:  dicovered.TokenEndpoint,
    	}
    
    	return authboss.OAuth2Provider{
    		OAuth2Config: cfg,
    		FindUserDetails: func(ctx context.Context, cfg oauth2.Config, token *oauth2.Token) (map[string]string, error) {
    			req, err := http.NewRequest("GET", dicovered.UserinfoEndpoint, nil)
    			if err != nil {
    				return nil, err
    			}
    			req.Header.Set("authorization", token.TokenType+" "+token.AccessToken)
    			userinfo := caosoidc.NewUserInfo()
    			if err := httphelper.HttpRequest(httpClient, req, &userinfo); err != nil {
    				return nil, err
    			}
    
    			user := map[string]string{
    				aboauth2.OAuth2UID: userinfo.GetSubject(),
    			}
    			if email := userinfo.GetEmail(); email != "" {
    				user[aboauth2.OAuth2Email] = email
    			}
    
    			return user, nil
    		},
    	}, nil
    }
    
    opened by oliverpool 2
Releases(v3.2.0)
Owner
Volatile Technologies Inc.
Volatile Technologies Inc.
vault-plugin-auth-usertotp is an auth method plugin for HashiCorp Vault.

vault-plugin-auth-usertotp is an auth method plugin for HashiCorp Vault. Create user accounts, add TOTP tokens (user supplied pin + totp), and have peace of mind using 2FA.

null 0 Jul 30, 2021
Gets Firebase auth tokens (for development purposes only)Gets Firebase auth tokens

Firebase Token Gets Firebase auth tokens (for development purposes only) Getting started Create Firebase project Setup Firebase authentication Setup G

MousyBusiness 1 Nov 17, 2021
HTTP-server-with-auth# HTTP Server With Authentication

HTTP-server-with-auth# HTTP Server With Authentication Introduction You are to use gin framework package and concurrency in golang and jwt-go to imple

Saba Sahban 12 May 12, 2022
Nsq http auth service for golang

nsq-auth nsq http auth service ./nsq-auth -h Usage: 2021/12/25 17:10:56 Usage:

纸喵 9 Apr 21, 2022
Provides AWS STS credentials based on Google Apps SAML SSO auth with interactive GUI support

What's this This command-line tool allows you to acquire AWS temporary (STS) credentials using Google Apps as a federated (Single Sign-On, or SSO) pro

Quan Hoang 30 Apr 29, 2022
Validate Django auth session in Golang

GoDjangoSession Valid for django 3.0.5 Usage: package main import ( "encoding/base64" "fmt" "session/auth" "github.com/Kuzyashin/GoDjangoSession"

Alexey Kuzyashin 26 Feb 13, 2022
Golang Mongodb Jwt Auth Example Using Echo

Golang Mongodb Jwt Auth Example Using Echo Golang Mongodb Rest Api Example Using Echo Prerequisites Golang 1.16.x Docker 19.03+ Docker Compose 1.25+ I

Şuayb Şimşek 6 Sep 21, 2021
Durudex Auth Service

⚡️ Durudex Auth Service Durudex Auth Service ?? Prerequisites Go 1.17 migrate grpc ⚙️ Build & Run Create an .env file in the root directory and add th

null 11 Apr 16, 2022
Figma Auth service for Haiku Animator

Figma Auth service for Haiku Animator In order to use Haiku Animator's Figma integration, a service must be running to perform OAuth2 token exchange.

Haiku 3 Feb 28, 2022
Golang Kalkancrypt Wrapper - simple digital signature auth service

Golang Kalkancrypt Wrapper WIP ⭐ Star on GitHub — it motivates me a lot! Overview Golang Kalkancrypt Wrapper - это простой веб-сервис для аутентификац

Abylaikhan Zulbukharov 44 May 4, 2022
Run multiple auth functions by relation

Relation Run multiple auth functions by relation. Signatures func New(relation string, conditions ...func(c *fiber.Ctx) bool) fiber.Handler Import imp

Eren BALCI 4 Oct 31, 2021
Auth Middleware for session & white-listed routing

Auth Middleware for session & white-listed routing

Joe Gasewicz 2 Nov 4, 2021
Auth Go microservice for managing authentication sessions

cryptomath-go-auth Auth Go microservice for managing authentication sessions. Install dependencies $ make deps Build $ make vendor $ make build Databa

Crypto Math 0 Mar 4, 2022
K8s controller to manage the aws-auth configmap

aws-auth-manager A kuberneres controller to manage the aws-auth configmap in EKS using a new AWSAuthItem CRD. The aws-auth configmap is used to give R

Matteo Ruina 11 Apr 20, 2022
Auth microservice for PRPO subject at UNI LJ

prpo-auth microservice This repository contains a source code for user management microservice used in a demo project developed under PRPO subject at

Žiga Patačko Koderman 0 Jan 7, 2022
JWT Auth in Golang

Credits This package used github.com/dgrijalva/jwt-go underhood and it heavily based on this post: http://www.inanzzz.com/index.php/post/kdl9/creating

Pablo Fuentes 0 Dec 12, 2021
Go Trakt Device Auth Library

A Go library to allow an end user to authorize a third-party Trakt application access to their account using the device method.

Brenek Harrison 0 Jan 7, 2022
Auth: a simple signup api for golang

auth This is a simple signup api You can access the db.go file and change the database credentials to your local postgres credentials. To run it prope

Gabriel Cervante 0 Jan 16, 2022
Goal: Develop a Go start auth starter without Gin framework

Goal: Develop a Go start auth starter without Gin framework and learn along the

Kai Hendry 2 Feb 1, 2022