首页 > 解决方案 > 使用自定义标题 WSO2

问题描述

我有两个应用程序,一个对某些用户进行身份验证并在用户有效时生成一个 jwt,然后将此 jwt 保存在名为 custom 的标题中,如您所见:

    var jwt = require('jsonwebtoken')
    var bodyParser = require('body-parser')

    app.use(bodyParser.urlencoded({extended: false}))
    app.use(bodyParser.json({limit:'10mb'}))

    app.post('/login', (req, res) => {

    let usuarios = [
    {
        username: "Hannibal",
        password: "pass1"
    },
    {
        username: "Arnold",
        password: "pass2"
    }
];

let credentials = req.body.credentials;

let isValid = usuarios.some((validUser) => {
    return validUser.username == credentials.username && validUser.password == credentials.password;
});

if (isValid){
var tokenData = {
  username: credentials.username
}

var token = jwt.sign(tokenData, 'Secret Password', {
  expiresIn: 60 * 60 * 24 // expires in 24 hours
})

res.setHeader("custom", token)

}

    res.json(
{
    "response": {
        "status": isValid
    }
});  
})

另一个验证 jwt。

    var jwt = require('jsonwebtoken')
    const express = require('express')
    const app = express()

    app.get('/secure', (req, res) => {
    var token = req.headers['custom']
    if(!token){
      res.status(401).send({
      error: "Es necesario el token de autenticación"
      })
       return
     }

   jwt.verify(token, 'Secret Password', function(err, user) {
     if (err) {
    res.status(401).send({
      error: 'Token inválido'
    })
  } else {
    res.send({
      message: 'Login exitoso!'
    })
  }
})
})

有可能做一个调用验证器的调解器,这个调解器获取自定义标头并验证它?我尝试使用这两个,但是当我尝试使用soap ui时,我不断收到401(缺少自定义令牌),直到我声明自定义头。

<?xml version="1.0" encoding="UTF-8"?>
  <sequence name="Mediator" trace="disable" 
    xmlns="http://ws.apache.org/ns/synapse">
    <call blocking="true" description="">
      <endpoint>
        <http method="get" uri-template="http://localhost:3001/secure"/>
      </endpoint>
    </call>
   </sequence>

<sequence name="passJWT" xmlns="http://ws.apache.org/ns/synapse">
<property expression="$trp:custom" name="custom" scope="transport" type="STRING"/>
<header expression="get-property('custom')" name="custom" scope="transport"/>

提前感谢任何指南或提示!

标签: node.jswso2synapse

解决方案


You should not need to touch your custom token in the meditaion sequence, when you send the message to your backend login service the custom header will get passed on.

A useful tool to help debug http headers to enable the http wire logs in conf/log4j.properties file. This will log the entire http payload to the logs so you can see the headers it is sending and receiving.

log4j.logger.org.apache.synapse.transport.http.wire=DEBUG

For an example I created this API with the middleman service that you are trying to create and a mock service for your backend token authentication.

<api context="/secureapi" name="LoginAPI" xmlns="http://ws.apache.org/ns/synapse">

    <!-- The Middleman API that your client app will talk to -->
    <resource methods="GET" protocol="http" url-mapping="/secure">
        <inSequence>
            <log level="custom">
                <property name="Secure service" expression="$trp:custom"/>
            </log>
            <property name="REST_URL_POSTFIX" action="remove" scope="axis2"/>
            <send>
                <endpoint>
                    <address uri="http://localhost:8280/secureapi/backend" format="rest"/>
                </endpoint>
            </send>
        </inSequence>
        <outSequence>
            <send/>
        </outSequence>
        <faultSequence/>
    </resource>


    <!-- This is a mock of you backend login service -->
    <resource methods="GET" protocol="http" url-mapping="/backend">
        <inSequence>
            <log level="custom">
                <property name="Backend" expression="$trp:custom"/>
            </log>
            <payloadFactory media-type="json">
                <format>
                    { message: 'Login exitoso!' }
                </format>
                <args/>
            </payloadFactory>
            <loopback/>
        </inSequence>
        <outSequence>
            <send/>
        </outSequence>
        <faultSequence/>
    </resource>
</api>

Removing the REST_URL_POSTFIX property is very important.

<property name="REST_URL_POSTFIX" action="remove" scope="axis2"/>

If i did not do this then the next time I try and send the message it will append /secure onto the end of it (so it will call http://localhost:8280/secureapi/backend/secure) which will result in a 404.

When I send a request to this API with the custom header set (I set the value to "jwtTokenString") the wso2carbon logs contain the following (I cut it down a bit to remove noise that is not important).

This is the middleman API receiving the request

[2018-06-07 16:45:24,957] [EI-Core] DEBUG - wire HTTP-Listener I/O dispatcher-4 >> "GET /secureapi/secure HTTP/1.1[\r][\n]"
[2018-06-07 16:45:24,957] [EI-Core] DEBUG - wire HTTP-Listener I/O dispatcher-4 >> "Host: my.host.name:8280[\r][\n]"
[2018-06-07 16:45:24,957] [EI-Core] DEBUG - wire HTTP-Listener I/O dispatcher-4 >> "Connection: keep-alive[\r][\n]"
[2018-06-07 16:45:24,957] [EI-Core] DEBUG - wire HTTP-Listener I/O dispatcher-4 >> "Cache-Control: no-cache[\r][\n]"
[2018-06-07 16:45:24,957] [EI-Core] DEBUG - wire HTTP-Listener I/O dispatcher-4 >> "User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/66.0.3359.181 Safari/537.36[\r][\n]"
[2018-06-07 16:45:24,957] [EI-Core] DEBUG - wire HTTP-Listener I/O dispatcher-4 >> "custom: jwtTokenString[\r][\n]"
[2018-06-07 16:45:24,958] [EI-Core] DEBUG - wire HTTP-Listener I/O dispatcher-4 >> "Postman-Token: ee489d08-ceb7-0cbe-de07-1544bf129c11[\r][\n]"
[2018-06-07 16:45:24,958] [EI-Core] DEBUG - wire HTTP-Listener I/O dispatcher-4 >> "Accept: */*[\r][\n]"
[2018-06-07 16:45:24,958] [EI-Core] DEBUG - wire HTTP-Listener I/O dispatcher-4 >> "Accept-Encoding: gzip, deflate[\r][\n]"
[2018-06-07 16:45:24,958] [EI-Core] DEBUG - wire HTTP-Listener I/O dispatcher-4 >> "Accept-Language: en-NZ,en;q=0.9,en-US;q=0.8[\r][\n]"
[2018-06-07 16:45:24,958] [EI-Core] DEBUG - wire HTTP-Listener I/O dispatcher-4 >> "[\r][\n]"

Then the Middle man API then logs the token

[2018-06-07 16:45:24,959] [EI-Core]  INFO - LogMediator Secure service = jwtTokenString

Next is the middle man API sending the message to the backend login service (note the direction of the angle brackets is different, >> = message in, << = message out)

[2018-06-07 16:45:24,961] [EI-Core] DEBUG - wire HTTP-Sender I/O dispatcher-4 << "GET /secureapi/backend HTTP/1.1[\r][\n]"
[2018-06-07 16:45:24,961] [EI-Core] DEBUG - wire HTTP-Sender I/O dispatcher-4 << "Accept: */*[\r][\n]"
[2018-06-07 16:45:24,961] [EI-Core] DEBUG - wire HTTP-Sender I/O dispatcher-4 << "Cache-Control: no-cache[\r][\n]"
[2018-06-07 16:45:24,961] [EI-Core] DEBUG - wire HTTP-Sender I/O dispatcher-4 << "custom: jwtTokenString[\r][\n]"
[2018-06-07 16:45:24,961] [EI-Core] DEBUG - wire HTTP-Sender I/O dispatcher-4 << "Postman-Token: ee489d08-ceb7-0cbe-de07-1544bf129c11[\r][\n]"
[2018-06-07 16:45:24,961] [EI-Core] DEBUG - wire HTTP-Sender I/O dispatcher-4 << "Accept-Encoding: gzip, deflate[\r][\n]"
[2018-06-07 16:45:24,961] [EI-Core] DEBUG - wire HTTP-Sender I/O dispatcher-4 << "Accept-Language: en-NZ,en;q=0.9,en-US;q=0.8[\r][\n]"
[2018-06-07 16:45:24,961] [EI-Core] DEBUG - wire HTTP-Sender I/O dispatcher-4 << "Host: localhost:8280[\r][\n]"
[2018-06-07 16:45:24,961] [EI-Core] DEBUG - wire HTTP-Sender I/O dispatcher-4 << "Connection: Keep-Alive[\r][\n]"
[2018-06-07 16:45:24,961] [EI-Core] DEBUG - wire HTTP-Sender I/O dispatcher-4 << "User-Agent: Synapse-PT-HttpComponents-NIO[\r][\n]"
[2018-06-07 16:45:24,961] [EI-Core] DEBUG - wire HTTP-Sender I/O dispatcher-4 << "[\r][\n]"

You can see that the custom header is still there. And finally the backend service receiving the message with the custom header

[2018-06-07 16:45:24,961] [EI-Core] DEBUG - wire HTTP-Listener I/O dispatcher-1 >> "GET /secureapi/backend HTTP/1.1[\r][\n]"
[2018-06-07 16:45:24,961] [EI-Core] DEBUG - wire HTTP-Listener I/O dispatcher-1 >> "Accept: */*[\r][\n]"
[2018-06-07 16:45:24,961] [EI-Core] DEBUG - wire HTTP-Listener I/O dispatcher-1 >> "Cache-Control: no-cache[\r][\n]"
[2018-06-07 16:45:24,961] [EI-Core] DEBUG - wire HTTP-Listener I/O dispatcher-1 >> "custom: jwtTokenString[\r][\n]"
[2018-06-07 16:45:24,961] [EI-Core] DEBUG - wire HTTP-Listener I/O dispatcher-1 >> "Postman-Token: ee489d08-ceb7-0cbe-de07-1544bf129c11[\r][\n]"
[2018-06-07 16:45:24,961] [EI-Core] DEBUG - wire HTTP-Listener I/O dispatcher-1 >> "Accept-Encoding: gzip, deflate[\r][\n]"
[2018-06-07 16:45:24,961] [EI-Core] DEBUG - wire HTTP-Listener I/O dispatcher-1 >> "Accept-Language: en-NZ,en;q=0.9,en-US;q=0.8[\r][\n]"
[2018-06-07 16:45:24,961] [EI-Core] DEBUG - wire HTTP-Listener I/O dispatcher-1 >> "Host: localhost:8280[\r][\n]"
[2018-06-07 16:45:24,961] [EI-Core] DEBUG - wire HTTP-Listener I/O dispatcher-1 >> "Connection: Keep-Alive[\r][\n]"
[2018-06-07 16:45:24,961] [EI-Core] DEBUG - wire HTTP-Listener I/O dispatcher-1 >> "User-Agent: Synapse-PT-HttpComponents-NIO[\r][\n]"
[2018-06-07 16:45:24,961] [EI-Core] DEBUG - wire HTTP-Listener I/O dispatcher-1 >> "[\r][\n]"

推荐阅读