Skip to content

Instantly share code, notes, and snippets.

@gistlyn
Last active March 12, 2019 04:55
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save gistlyn/e22cd558e789a8b6424ba4fbac14de1d to your computer and use it in GitHub Desktop.
Save gistlyn/e22cd558e789a8b6424ba4fbac14de1d to your computer and use it in GitHub Desktop.
AuthFeature configured with Credentials AuthProvider and Memory AuthRepository, Cache Client and Admin User
using System.Collections.Generic;
using Funq;
using ServiceStack;
using ServiceStack.Auth;
using ServiceStack.Caching;
using ServiceStack.Configuration;
using ServiceStack.FluentValidation;
namespace MyApp
{
// Run before AppHost.Configure()
public class ConfigureAuth : IConfigureAppHost
{
public void Configure(IAppHost appHost)
{
var AppSettings = appHost.AppSettings;
appHost.Plugins.Add(new AuthFeature(() => new CustomUserSession(),
new IAuthProvider[] {
new CredentialsAuthProvider(), //Enable UserName/Password Credentials Auth
}));
appHost.Plugins.Add(new RegistrationFeature()); //Enable /register Service
//override the default registration validation with your own custom implementation
appHost.RegisterAs<CustomRegistrationValidator, IValidator<Register>>();
appHost.Register<ICacheClient>(new MemoryCacheClient()); //Store User Sessions in Memory
appHost.Register<IAuthRepository>(new InMemoryAuthRepository()); //Store Authenticated Users in Memory
CreateUser(appHost, "admin@email.com", "Admin User", "p@55wOrd", roles:new[]{ RoleNames.Admin });
}
// Add initial Users to the configured Auth Repository
public void CreateUser(IAppHost appHost, string email, string name, string password, string[] roles)
{
var authRepo = appHost.TryResolve<IAuthRepository>();
var newAdmin = new UserAuth { Email = email, DisplayName = name };
var user = authRepo.CreateUserAuth(newAdmin, password);
authRepo.AssignRoles(user, roles);
}
}
// Type class to store additional metadata in Users Session
public class CustomUserSession : AuthUserSession {}
// Custom Validator to add custom validators to built-in /register Service requiring DisplayName and ConfirmPassword
public class CustomRegistrationValidator : RegistrationValidator
{
public CustomRegistrationValidator()
{
RuleSet(ApplyTo.Post, () =>
{
RuleFor(x => x.DisplayName).NotEmpty();
RuleFor(x => x.ConfirmPassword).NotEmpty();
});
}
}
}
<h3 class="pt-4 pb-2">Sign In using credentials</h3>
<form action="/auth/credentials" method="post" class="col-lg-7">
<div class="form-row">
<div class="form-group" data-validation-summary="userName,password"></div>
</div>
<div class="form-row">
<div class="form-group">
<input class="form-control form-control-lg" name="userName" type="text" placeholder="UserName">
</div>
</div>
<div class="form-row">
<div class="form-group">
<input class="form-control form-control-lg" name="password" type="password" placeholder="Password">
</div>
</div>
<div class="form-row">
<div class="form-group">
<input type="checkbox" id="rememberMe" name="rememberMe" value="true">
<label for="rememberMe">Remember Me</label>
</div>
</div>
<div class="form-group">
<div class="form-group">
<button type="submit" class="btn btn-lg btn-primary">Login</button>
</div>
</div>
<div class="form-group">
<a class="lnk" href="{{ '/signup' | addQueryString({ qs.redirect }) }}">Register New User</a>
</div>
</form>
<script>var CONTINUE = '{{qs.redirect ?? "/"}}';</script>
<script>!window["@servicestack/client"] && document.write(unescape('%3Cscript src="https://unpkg.com/@servicestack/client/dist/servicestack-client.umd.js"%3E%3C/script%3E'));</script>
<script>
(function(_){
_.bootstrapForm(document.querySelector('form'), {
success: function(r) {
location.href = CONTINUE;
}
});
})(window["@servicestack/client"]);
</script>
<h3 class="pt-4 pb-2">Register New User</h3>
<form action="/register" method="post" class="col-lg-7">
<div class="form-row">
<div class="form-group" data-validation-summary="displayName,email,password,confirmPassword"></div>
</div>
<div class="form-group">
<input class="form-control form-control-lg" name="displayName" type="text" placeholder="Display Name">
</div>
<div class="form-group">
<input class="form-control form-control-lg" name="email" type="text" placeholder="Email">
</div>
<div class="form-group">
<input class="form-control form-control-lg" name="password" type="password" placeholder="Password">
</div>
<div class="form-group">
<input class="form-control form-control-lg" name="confirmPassword" type="password" placeholder="Confirm Password">
</div>
<div class="form-group">
<input type="checkbox" id="autoLogin" name="autoLogin" value="true" checked>
<label for="autoLogin" class="form-check-label">Auto Login</label>
</div>
<div class="form-group">
<button class="btn btn-lg btn-primary" type="submit">Register</button>
</div>
</form>
<script>var CONTINUE = '{{qs.redirect ?? "/"}}';</script>
<script>!window["@servicestack/client"] && document.write(unescape('%3Cscript src="https://unpkg.com/@servicestack/client/dist/servicestack-client.umd.js"%3E%3C/script%3E'));</script>
<script>
(function(_){
_.bootstrapForm(document.querySelector('form'), {
success: (r) => {
location.href = CONTINUE;
}
});
})(window["@servicestack/client"]);
</script>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment