5
0
Fork 0

Added capability for auth to read tokens from querystring.

master
UnicodingUnicorn 2019-03-23 19:42:16 +08:00
parent 6986ae3eb5
commit 391f060744
3 changed files with 29 additions and 2 deletions

View File

@ -12,3 +12,4 @@ router = "0.6.0"
jsonwebtoken = "5"
serde = { version = "1.0", features = [ "derive" ] }
serde_json = "1.0"
urlencoded = "0.6.0"

View File

@ -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?
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`
@ -12,3 +12,7 @@ Is basically tailored just for traefik's Forward Authentication system. It takes
"clientid": "<clientid>"
}
```
## Errors
`auth` responses with `400` if there is no token supplied, or `401` if there is an error processing the token.

View File

@ -7,12 +7,14 @@ extern crate dotenv;
extern crate iron;
extern crate router;
extern crate jsonwebtoken as jwt;
extern crate urlencoded;
use dotenv::dotenv;
use iron::prelude::*;
use iron::headers::{ Authorization, Bearer };
use iron::status::Status;
use router::Router;
use urlencoded::UrlEncodedQuery;
use std::env;
#[derive(Debug, Serialize, Deserialize)]
@ -31,8 +33,28 @@ fn main() {
}
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>>() {
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
Ok(decoded) => {
let user_string = match serde_json::to_string(&decoded.claims) {