Steam Authentication with Steam4J-Auth

Steam’s OpenID-based authentication enables site visitors to login using their steam credentials without your site having to store or manage the credentials directly thereby reducing the amount of sensitive data that could be leaked in the event of a data breach.

Steam authorisation is based on the OpenID spec, as such when implemented properly should provide sufficient confidence that the user is who they say they are.

This article explains how to authenticate a steam account using the Steam4J-Auth module from the 3rd party Steam4J library.

The workflow

Let’s look at the workflow from the user’s perspective using as an example.

User visiting decides they want to make an edit to their wishlist, before they can do this, they must first login, so the user clicks on the login button to sign in. The user is redirected to steam where they are asked to provide their username and password, (and their 2 factor authentication code if necessary), if they successfully login, they are redirected back to and the user is now able to edit their wishlist.

The workflow is relatively simple from the user’s perspective and probably explains why OpenId and similar authentication systems have gained so much traction.

Behind the scenes

This is what needs to happen behind the scenes in order to authenticate a user:

  • The website must be secured by https.
  • User clicks a login button which links to the openId site.
  • Steam examines the URL query parameters noting the openId.mode is set to ‘check_authorisation’, together with a redirect parameter which should be an endpoint on
  • The user enters their credentials into
  • Steam validates these credentials, and then redirects the user to the endpoint which was specified in the initial request.
  • In order to validate the user, examines the query parameters provided by steam, in particular the ‘claimedId’ and the signature.
  • server (never the client side) calls the endpoint back, passing the given request parameters and the signature.
  • checks if the signature is valid for the set of parameters provided.
  • also handles nonce expiration, so the same signature + claimedId pair cannot be replayed.

In summary, provides a signed set of claims to the client, the client submits these claims to the backend, and the backend verifies these claims with, it is the up to to store the user in a signed/encrypted cookie and then check the entitlements of that user against it’s own database.

Note that you absolutely must make the call to to verify the claim provided by the client, since without this signature based check, the claimedId is meaningless (i.e. anybody can change the claimedId).


The steam4j library provides a module called steam4j-auth which can help us implement authorisation in our applications.

In particular, the SteamAuth class provides several useful helper methods for implementing the above workflow.

SteamAuth is thread safe so a spring managed singleton used across your application is fine, to construct simply provide the ‘realm’ (the domain of your site) and ‘redirect’ url for example:

SteamAuth sa = new SteamAuth("", "");

sa.getLoginUrl() returns a string representation of the URL which the login button should link to. It contains the realm, and redirect url, as well as boiler plate parameters required. You can of course expose this link via an endpoint.

sa.authenticate(HttpServletRequest r) examines the given HttpServletRequest for the claimedId and the signature, verifies this with steam, and returns an Authorisation result which states if the login is successful, you can then based on this issue a signed cookie containing this information. Assuming you are using Spring’s REST related annotations, this method is useful since you can pass the HttpServletRequest from your endpoint directly to the authenticate method.

Example usage

Finally, here is an illustration of what a Spring rest endpoint might look like:

public class LoginController {
    private final SteamAuth steamAuth;

    //this method can be called by your javascript client to figure out where to redirect 
    //the user when the login button is clicked
    public @ResponseBody JsonNode generateSteamUrl(HttpServletRequest request) {"Logging in");
        try {
            return new TextNode(steamAuth.getLoginUrl());
        } catch (Exception e) {
            throw new SteamAPIDown();

    //this method gets called when redirects to the site on successful login
    //you must call steamAuth.authenticate(request) in order to verify the claimedId.
    //In this method we don’t show you how to set a signed cookie, only where it should be done
    public @ResponseBody boolean openIDCallback(HttpServletRequest request, HttpServletResponse response) {
        AuthorizationResult result = steamAuth.authenticate(request);
        if (result.isSuccess()) {
            //perform signed cookie set here
  "{} logged in ", result.getUserId());
            return true;
        } else {
            return false;

    //SteamAuth instance provided via dependency injection
    public SessionController(SteamAuth steamAuth) {
        this.steamAuth = steamAuth;