Added capability for auth to read tokens from querystring.
parent
6986ae3eb5
commit
391f060744
|
@ -12,3 +12,4 @@ router = "0.6.0"
|
||||||
jsonwebtoken = "5"
|
jsonwebtoken = "5"
|
||||||
serde = { version = "1.0", features = [ "derive" ] }
|
serde = { version = "1.0", features = [ "derive" ] }
|
||||||
serde_json = "1.0"
|
serde_json = "1.0"
|
||||||
|
urlencoded = "0.6.0"
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
|
|
||||||
Beep backend auth proxy. At long last, something done properly in Rust. My ancestors are smiling at me, Imperial, can you say the same?
|
Beep backend auth proxy. At long last, something done properly in Rust. My ancestors are smiling at me, Imperial, can you say the same?
|
||||||
|
|
||||||
Is basically tailored just for traefik's Forward Authentication system. It takes a `GET`, `POST`, `PUT`, `PATCH` or `DELETE` request, reads a Bearer Auth JWT token if available. If it is not available or invalid, request fails with 4XX and traefik rejects the request. Otherwise, a success response is returned with a `X-User-Claim` header containing serialised user information. `OPTIONS` requests are allowed to pass through wholesale.
|
Is basically tailored just for traefik's Forward Authentication system. It takes a `GET`, `POST`, `PUT`, `PATCH` or `DELETE` request, reads a Bearer Auth JWT token if available. Alternatively, the token can be supplied in the querystring as `token`. Tokens in the Authorization header override tokens in the querystring. If it is not available or invalid, request fails with 4XX and traefik rejects the request. Otherwise, a success response is returned with a `X-User-Claim` header containing serialised user information. `OPTIONS` requests are allowed to pass through wholesale.
|
||||||
|
|
||||||
## Contents of `X-User-Claim`
|
## Contents of `X-User-Claim`
|
||||||
|
|
||||||
|
@ -12,3 +12,7 @@ Is basically tailored just for traefik's Forward Authentication system. It takes
|
||||||
"clientid": "<clientid>"
|
"clientid": "<clientid>"
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
## Errors
|
||||||
|
|
||||||
|
`auth` responses with `400` if there is no token supplied, or `401` if there is an error processing the token.
|
||||||
|
|
24
src/main.rs
24
src/main.rs
|
@ -7,12 +7,14 @@ extern crate dotenv;
|
||||||
extern crate iron;
|
extern crate iron;
|
||||||
extern crate router;
|
extern crate router;
|
||||||
extern crate jsonwebtoken as jwt;
|
extern crate jsonwebtoken as jwt;
|
||||||
|
extern crate urlencoded;
|
||||||
|
|
||||||
use dotenv::dotenv;
|
use dotenv::dotenv;
|
||||||
use iron::prelude::*;
|
use iron::prelude::*;
|
||||||
use iron::headers::{ Authorization, Bearer };
|
use iron::headers::{ Authorization, Bearer };
|
||||||
use iron::status::Status;
|
use iron::status::Status;
|
||||||
use router::Router;
|
use router::Router;
|
||||||
|
use urlencoded::UrlEncodedQuery;
|
||||||
use std::env;
|
use std::env;
|
||||||
|
|
||||||
#[derive(Debug, Serialize, Deserialize)]
|
#[derive(Debug, Serialize, Deserialize)]
|
||||||
|
@ -31,8 +33,28 @@ fn main() {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn verify_jwt(req:&mut Request) -> IronResult<Response> {
|
fn verify_jwt(req:&mut Request) -> IronResult<Response> {
|
||||||
|
let mut token = None;
|
||||||
|
|
||||||
|
// Check token from querystring
|
||||||
|
match req.get_ref::<UrlEncodedQuery>() {
|
||||||
|
Ok(ref hashmap) => {
|
||||||
|
if let Some(token_vec) = hashmap.get("token") {
|
||||||
|
if !token_vec.is_empty() {
|
||||||
|
token = Some(token_vec[0].clone());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
Err(_) => return Ok(Response::with((Status::BadRequest, "400 Bad Request"))),
|
||||||
|
};
|
||||||
|
|
||||||
|
// Check token from Authorization header
|
||||||
if let Some(authorisation_header) = req.headers.get::<Authorization<Bearer>>() {
|
if let Some(authorisation_header) = req.headers.get::<Authorization<Bearer>>() {
|
||||||
match jwt::decode::<UserClaims>(&authorisation_header.token, secret.as_ref(), &jwt::Validation{ validate_exp:false, ..Default::default()}) { // Don't validate expiry
|
token = Some(authorisation_header.token.clone());
|
||||||
|
}
|
||||||
|
|
||||||
|
// Process token
|
||||||
|
if let Some(token) = token {
|
||||||
|
match jwt::decode::<UserClaims>(&token, secret.as_ref(), &jwt::Validation{ validate_exp:false, ..Default::default()}) { // Don't validate expiry
|
||||||
// match jwt::decode::<UserClaims>(&authorisation_header.token, secret.as_ref(), &jwt::Validation::default()) { // Production version
|
// match jwt::decode::<UserClaims>(&authorisation_header.token, secret.as_ref(), &jwt::Validation::default()) { // Production version
|
||||||
Ok(decoded) => {
|
Ok(decoded) => {
|
||||||
let user_string = match serde_json::to_string(&decoded.claims) {
|
let user_string = match serde_json::to_string(&decoded.claims) {
|
||||||
|
|
Loading…
Reference in New Issue