Navigation Menu

Skip to content

Instantly share code, notes, and snippets.

@dgwaldo
Last active August 1, 2018 13:31
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 dgwaldo/152d1f52c69e603930d946fdc9055662 to your computer and use it in GitHub Desktop.
Save dgwaldo/152d1f52c69e603930d946fdc9055662 to your computer and use it in GitHub Desktop.
Swashbuckle - Auth0 Implicit Grant
[ApiExplorerSettings(IgnoreApi = true)]
[AllowAnonymous]
[Route("api/[controller]")]
[ApiController]
public class AuthenticationController : ControllerBase {
private readonly Auth0Settings _auth0Settings;
public AuthenticationController(
IOptions<Auth0Settings> auth0Settings
) {
_auth0Settings = auth0Settings.Value;
}
[HttpGet]
public IActionResult GetToken() {
var url = $"{_auth0Settings.AuthUrl}" +
$"?audience={_auth0Settings.Audience}" +
$"&scope=openid email&response_type=token&client_id={_auth0Settings.ClientId}&connection={_auth0Settings.Connection}" +
$"&redirect_uri={_auth0Settings.RedirectUri}";
return Redirect(url);
}
}
<!-- Only body shown here for brevity -->
<body>
<div>
<a class="auth-btn" href="api/authentication">Get Auth Token</a>
</div>
<div id="swagger-ui"></div>
<script src="./swagger-ui-bundle.js"></script>
<script src="./swagger-ui-standalone-preset.js"></script>
<script>
window.onload = function () {
// If the URL has a token, pull it out and throw it into a prompt so the user can grab it for the clipboard.
var token = getUrlVar("access_token");
if (token) {
prompt("Copy to clipboard: Ctrl + C, Enter", "Bearer " + token);
}
var configObject = JSON.parse('{"urls":[{"url":"/swagger/v1/swagger.json","name":"API V1"}],"validatorUrl":null,"defaultModelExpandDepth":0,"defaultModelsExpandDepth":-1,"displayRequestDuration":true,"docExpansion":"list"}');
var oauthConfigObject = JSON.parse('{}');
// Apply mandatory parameters
configObject.dom_id = "#swagger-ui";
configObject.presets = [SwaggerUIBundle.presets.apis, SwaggerUIStandalonePreset];
configObject.layout = "StandaloneLayout";
// If oauth2RedirectUrl isn't specified, use the built-in default
if (!configObject.hasOwnProperty("oauth2RedirectUrl"))
configObject.oauth2RedirectUrl = window.location.href.replace("index.html", "oauth2-redirect.html");
// Build a system
const ui = SwaggerUIBundle(configObject);
// Apply OAuth config
ui.initOAuth(oauthConfigObject);
}
function getUrlVar(key) {
var result = new RegExp(key + "=([^&]*)", "i").exec(window.location.hash);
return result && unescape(result[1]) || "";
}
</script>
</body>
public class Startup {
private AppConfig _appConfig;
public Startup(IConfiguration configuration) {
Configuration = configuration;
}
public IConfiguration Configuration { get; }
// This method gets called by the runtime. Use this method to add services to the container.
public void ConfigureServices(IServiceCollection services) {
_appConfig = new AppConfig();
Configuration.GetSection("App").Bind(_appConfig);
services.Configure<Auth0Settings>(Configuration.GetSection("App").GetSection("Auth0Settings"));
services.AddHttpClient("Auth0UserInfo");
services.AddSwaggerGen(c => {
c.AddSecurityDefinition("Bearer", new ApiKeyScheme() {
Description = "JWT Authorization header using the Bearer scheme. Example: \"Bearer {token}\"",
Name = "Authorization",
In = "header",
Type = "apiKey"
});
c.AddSecurityRequirement(new Dictionary<string, IEnumerable<string>>{
{ "Bearer", new string[] { } }
});
c.SwaggerDoc("v1", new Info { Title = "Data API", Version = "v1" });
c.OperationFilter<FileUploadOperation>();
c.DescribeAllEnumsAsStrings();
});
services.AddAuthentication(options => {
options.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
options.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;
}).AddJwtBearer(options => {
options.Authority = _appConfig.Auth0Settings.Authority;
options.Audience = _appConfig.Auth0Settings.Audience;
options.Events = new JwtBearerEvents {
OnTokenValidated = async (context) => {
var client = httpClient.CreateClient("Auth0UserInfo");
client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", (context.SecurityToken as JwtSecurityToken).RawData);
var response = await client.GetAsync($"{options.Authority}/userinfo");
var userInfo = await response.Content.ReadAsStringAsync();
var user = JsonConvert.DeserializeObject<UserInfo>(userInfo);
(context.Principal.Identity as ClaimsIdentity).AddClaim(new Claim(ClaimTypes.Email, user.Email));
}
};
});
services.AddMvc()
.AddJsonOptions(x => x.SerializerSettings.ReferenceLoopHandling = Newtonsoft.Json.ReferenceLoopHandling.Ignore)
.SetCompatibilityVersion(CompatibilityVersion.Version_2_1);
}
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
public void Configure(IApplicationBuilder app, IHostingEnvironment env, DataGraphContext db) {
if (env.IsDevelopment()) {
app.UseDeveloperExceptionPage();
} else {
app.UseHsts();
}
app.UseSwagger();
app.UseSwaggerUI(c => {
c.RoutePrefix = String.Empty;
c.SwaggerEndpoint("/swagger/v1/swagger.json", "API V1");
c.DefaultModelExpandDepth(0);
c.DefaultModelsExpandDepth(-1);
c.DisplayRequestDuration();
c.DocExpansion(DocExpansion.List);
c.IndexStream = () => GetType().GetTypeInfo().Assembly.GetManifestResourceStream("Project.API.Swagger.index.html");
});
app.UseAuthentication();
app.UseMvc();
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment