View Issue Details

IDProjectCategoryView StatusLast Update
0027349mantisbtapi restpublic2020-10-17 12:57
Reportere4rthdog Assigned Todregad  
PriorityhighSeveritymajorReproducibilityalways
Status closedResolutionno change required 
Product Version2.22.1 
Summary0027349: Cannot disable anonymous API access
Description

I want to use API and to secure it by using tokens.

I dont have an anonymous user and my projects are private.

My problem is that me api is public and anyone can use it with out token.

How can i configure Mantis to always use token for the REST API?

TagsNo tags attached.

Activities

dregad

dregad

2020-09-25 09:11

developer   ~0064483

Did you read https://mantisbt.org/docs/master/en-US/Admin_Guide/html-desktop/#admin.config.api ?
You probably want to set $g_webservice_readonly_access_level_threshold

e4rthdog

e4rthdog

2020-09-25 10:01

reporter   ~0064484

Last edited: 2020-09-25 10:03

After the changes int he config i have another issue.

I issued a token from mantis and i am using it with axios (javascript). I am getting error 401 without kowing what is wrong:

My Code

await axios.get(url, {
                headers: { 'Authorization' : 'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXX' }
            })
                .then(function (response) {
                    console.log(response.data.issues[0].summary);
                })
                .catch(function (error) {
                    console.log(error);
                })

The error:

Error: Request failed with status code 401
    at createError (g:\_DEV\hgi-discord\bot-js\node_modules\axios\lib\core\createError.js:16:15)
    at settle (g:\_DEV\hgi-discord\bot-js\node_modules\axios\lib\core\settle.js:17:12)
    at IncomingMessage.handleStreamEnd (g:\_DEV\hgi-discord\bot-js\node_modules\axios\lib\adapters\http.js:244:11)
    at IncomingMessage.emit (events.js:205:15)
    at endReadableNT (_stream_readable.js:1154:12)
    at processTicksAndRejections (internal/process/task_queues.js:74:11) {
  config: {
    url: 'http://help.hgi.gr/api/rest/issues/81',
    method: 'get',
    headers: {
      Accept: 'application/json, text/plain, */*',
      Authorization: 'xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx',
      'User-Agent': 'axios/0.20.0'
    },
    transformRequest: [ [Function: transformRequest] ],
    transformResponse: [ [Function: transformResponse] ],
    timeout: 0,
    adapter: [Function: httpAdapter],
    xsrfCookieName: 'XSRF-TOKEN',
    xsrfHeaderName: 'X-XSRF-TOKEN',
    maxContentLength: -1,
    maxBodyLength: -1,
    validateStatus: [Function: validateStatus],
    data: undefined
  },
  request: ClientRequest {
    _events: [Object: null prototype] {
      socket: [Function],
      abort: [Function],
      aborted: [Function],
      connect: [Function],
      error: [Function],
      timeout: [Function],
      prefinish: [Function: requestOnPrefinish]
    },
    _eventsCount: 7,
    _maxListeners: undefined,
    outputData: [],
    outputSize: 0,
    writable: true,
    _last: true,
    chunkedEncoding: false,
    shouldKeepAlive: false,
    useChunkedEncodingByDefault: false,
    sendDate: false,
    _removedConnection: false,
    _removedContLen: false,
    _removedTE: false,
    _contentLength: 0,
    _hasBody: true,
    _trailer: '',
    finished: true,
    _headerSent: true,
    socket: Socket {
      connecting: false,
      _hadError: false,
      _parent: null,
      _host: 'help.hgi.gr',
      _readableState: [ReadableState],
      readable: true,
      _events: [Object: null prototype],
      _eventsCount: 7,
      _maxListeners: undefined,
      _writableState: [WritableState],
      writable: false,
      allowHalfOpen: false,
      _sockname: null,
      _pendingData: null,
      _pendingEncoding: '',
      server: null,
      _server: null,
      parser: null,
      _httpMessage: [Circular],
      [Symbol(asyncId)]: 62,
      [Symbol(kHandle)]: [TCP],
      [Symbol(lastWriteQueueSize)]: 0,
      [Symbol(timeout)]: null,
      [Symbol(kBytesRead)]: 0,
      [Symbol(kBytesWritten)]: 0
    },
    connection: Socket {
      connecting: false,
      _hadError: false,
      _parent: null,
      _host: 'help.hgi.gr',
      _readableState: [ReadableState],
      readable: true,
      _events: [Object: null prototype],
      _eventsCount: 7,
      _maxListeners: undefined,
      _writableState: [WritableState],
      writable: false,
      allowHalfOpen: false,
      _sockname: null,
      _pendingData: null,
      _pendingEncoding: '',
      server: null,
      _server: null,
      parser: null,
      _httpMessage: [Circular],
      [Symbol(asyncId)]: 62,
      [Symbol(kHandle)]: [TCP],
      [Symbol(lastWriteQueueSize)]: 0,
      [Symbol(timeout)]: null,
      [Symbol(kBytesRead)]: 0,
      [Symbol(kBytesWritten)]: 0
    },
    _header: 'GET /api/rest/issues/81 HTTP/1.1\r\n' +
      'Accept: application/json, text/plain, */*\r\n' +
      'Authorization: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx\r\n' +
      'User-Agent: axios/0.20.0\r\n' +
      'Host: help.hgi.gr\r\n' +
      'Connection: close\r\n' +
      '\r\n',
    _onPendingData: [Function: noopPendingOutput],
    agent: Agent {
      _events: [Object: null prototype],
      _eventsCount: 1,
      _maxListeners: undefined,
      defaultPort: 80,
      protocol: 'http:',
      options: [Object],
      requests: {},
      sockets: [Object],
      freeSockets: {},
      keepAliveMsecs: 1000,
      keepAlive: false,
      maxSockets: Infinity,
      maxFreeSockets: 256
    },
    socketPath: undefined,
    method: 'GET',
    path: '/api/rest/issues/81',
    _ended: true,
    res: IncomingMessage {
      _readableState: [ReadableState],
      readable: false,
      _events: [Object: null prototype],
      _eventsCount: 3,
      _maxListeners: undefined,
      socket: [Socket],
      connection: [Socket],
      httpVersionMajor: 1,
      httpVersionMinor: 1,
      httpVersion: '1.1',
      complete: true,
      headers: [Object],
      rawHeaders: [Array],
      trailers: {},
      rawTrailers: [],
      aborted: false,
      upgrade: false,
      url: '',
      method: null,
      statusCode: 401,
      statusMessage: 'API token required',
      client: [Socket],
      _consuming: false,
      _dumped: false,
      req: [Circular],
      responseUrl: 'http://help.hgi.gr/api/rest/issues/81',
      redirects: []
    },
    aborted: false,
    timeoutCb: null,
    upgradeOrConnect: false,
    parser: null,
    maxHeadersCount: null,
    _redirectable: Writable {
      _writableState: [WritableState],
      writable: true,
      _events: [Object: null prototype],
      _eventsCount: 2,
      _maxListeners: undefined,
      _options: [Object],
      _ended: true,
      _ending: true,
      _redirectCount: 0,
      _redirects: [],
      _requestBodyLength: 0,
      _requestBodyBuffers: [],
      _onNativeResponse: [Function],
      _currentRequest: [Circular],
      _currentUrl: 'http://help.hgi.gr/api/rest/issues/81'
    },
    [Symbol(isCorked)]: false,
    [Symbol(outHeadersKey)]: [Object: null prototype] {
      accept: [Array],
      authorization: [Array],
      'user-agent': [Array],
      host: [Array]
    }
  },
  response: {
    status: 401,
    statusText: 'API token required',
    headers: {
      date: 'Fri, 25 Sep 2020 13:54:07 GMT',
      server: 'Apache',
      'x-mantis-version': '2.22.1',
      'cache-control': 'no-store, no-cache, must-revalidate, max-age=0',
      'set-cookie': [Array],
      upgrade: 'h2,h2c',
      connection: 'Upgrade, close',
      'last-modified': 'Thu, 26 Sep 2019 16:45:58 GMT',
      'content-length': '0',
      'host-header': 'c2hhcmVkLmJsdWVob3N0LmNvbQ==',
      'content-type': 'text/html; charset=UTF-8'
    },
    config: {
      url: 'http://help.hgi.gr/api/rest/issues/81',
      method: 'get',
      headers: [Object],
      transformRequest: [Array],
      transformResponse: [Array],
      timeout: 0,
      adapter: [Function: httpAdapter],
      xsrfCookieName: 'XSRF-TOKEN',
      xsrfHeaderName: 'X-XSRF-TOKEN',
      maxContentLength: -1,
      maxBodyLength: -1,
      validateStatus: [Function: validateStatus],
      data: undefined
    },
    request: ClientRequest {
      _events: [Object: null prototype],
      _eventsCount: 7,
      _maxListeners: undefined,
      outputData: [],
      outputSize: 0,
      writable: true,
      _last: true,
      chunkedEncoding: false,
      shouldKeepAlive: false,
      useChunkedEncodingByDefault: false,
      sendDate: false,
      _removedConnection: false,
      _removedContLen: false,
      _removedTE: false,
      _contentLength: 0,
      _hasBody: true,
      _trailer: '',
      finished: true,
      _headerSent: true,
      socket: [Socket],
      connection: [Socket],
      _header: 'GET /api/rest/issues/81 HTTP/1.1\r\n' +
        'Accept: application/json, text/plain, */*\r\n' +
        'Authorization: xxxxxxxxxxxxxxxxxxxxxxxx\r\n' +
        'User-Agent: axios/0.20.0\r\n' +
        'Host: help.hgi.gr\r\n' +
        'Connection: close\r\n' +
        '\r\n',
      _onPendingData: [Function: noopPendingOutput],
      agent: [Agent],
      socketPath: undefined,
      method: 'GET',
      path: '/api/rest/issues/81',
      _ended: true,
      res: [IncomingMessage],
      aborted: false,
      timeoutCb: null,
      upgradeOrConnect: false,
      parser: null,
      maxHeadersCount: null,
      _redirectable: [Writable],
      [Symbol(isCorked)]: false,
      [Symbol(outHeadersKey)]: [Object: null prototype]
    },
    data: ''
  },
  isAxiosError: true,
  toJSON: [Function: toJSON]
}
e4rthdog

e4rthdog

2020-09-26 00:51

reporter   ~0064486

The solution that worked for me when i get error 401 on the api is to add the following to the .htaccess in the /api/rest directory:

SetEnvIf Authorization .+ HTTP_AUTHORIZATION=$0
dregad

dregad

2020-09-26 06:11

developer   ~0064487

Thanks for the feedback and glad to hear you found a solution to your problem.

This works just fine for me without altering .htaccess, so it would be interesting to know, why your server is dropping the Authorization header.

e4rthdog

e4rthdog

2020-09-26 06:24

reporter   ~0064488

I couldn't find out ...I thought it was the php-fpm module but it is not enabled.....Since it is shared hosting i think that i will never be able to know why :)

dregad

dregad

2020-09-26 06:38

developer   ~0064489

OK, in that case I'll close this as no change required since the problem seems to be specific to your environment.