FTN8.3: FutoIn Security Concept - Client Authentication Version: 0.2DV Date: 2017-12-27 Copyright: 2014-2018 FutoIn Project (http://futoin.org) Authors: Andrey Galkin
This sub-specification of FTN8 covers Client authentication and Service authorization.
Client is assumed to be a software under control of User. User is a living being like human.
The ultimate goal is to concentrate primary User and Client authentication logic in AuthService as defined in the main spec while Service itself has minimal responsibility.
There is an open list of possible use cases:
At least for HTTP-based Clients, there is doubtful security of using stateless or MAC-based request signing authentication as modern browsers support protection of cookies from exposure to applications on page.
Therefore, this sub-spec is focused on cookie-based authentication. The cookie must be bound to particular Service. It must not be possible to re-use it in other Service.
PleaseReauth
standard error is thrownPleaseReauth
handling in Client codeNote: this logic does not apply to Service-to-Service calls
It's assumed that single Client can have multiple User sessions at the same time.
Therefore:
More details are provided in FTN8.6 sub-spec.
More details of Service authorization to access User's resources on different Services is described in the main FTN8 spec and FTN8.4 sub-spec.
"Auth Query" stays both for "Authentication" and for "Authorization" query. The second always depends on the first one, but plain authentication query without asking for any resource authorization can be done. In scope of the spec, User authentication can be seen as authorization of Service to get basic User's local and global ID.
User private information available in AuthService is accessible through dedicated interface. So, there is no special handling compared to any other resources.
To request User authorization for some resources, Service may request AuthService to ask User to grant access of owned and/or controlled resources in another location.
The important aspects:
declareAccessControl()
is called by Services once per new software version.AuthQueryRequest
payload with access control descriptors of ServiceB.EXPOSED
signing key from Master Secret and signed the payload with the key.auth_url
concatenated with the payload encoded in Base64.AuthQueryResponse
using new timestamp, but the same nonce and signing key.result_url
concatenated with Base64 encoded payload.startSession()
.resumeSession()
once in 10 minutes, if session is used.closeSession()
must be called.Service should listen to AuthService events through FTN18 Event Stream interface.
SESS_END
- event type:local_id
global_id
session_token
{
"iface" : "futoin.auth.service",
"version" : "{ver}",
"ftn3rev" : "1.8",
"imports" : [
"futoin.ping:1.0",
"futoin.auth.types:{ver}"
],
"types" : {
"TemplateName" : {
"type" : "GenericIdentifier",
"maxlen" : 32
},
"SessionStartToken" : {
"type" : "Base64",
"minlen" : 22,
"maxlen" : 171
},
"SessionToken" : {
"type" : "Base64",
"minlen" : 22,
"maxlen" : 171
},
"AuthQueryID" : "UUIDB64",
"AuthQueryNonce" : {
"type" : "Base64",
"maxlen" : 22
},
"AuthQueryRequest" : {
"type" : "map",
"fields" : {
"id" : "AuthQueryID",
"ts" : "Timestamp",
"nonce" : "AuthQueryNonce",
"msid" : "MasterSecretID"
}
},
"AuthQueryResponse" : {
"type" : "map",
"fields" : {
"token" : "SessionStartToken",
"ts" : "Timestamp",
"nonce" : "AuthQueryNonce",
"msid" : "MasterSecretID"
}
}
},
"funcs" : {
"declareAccessControl" : {
"params" : {
"access_groups" : "AccessGroupList"
},
"result" : "boolean"
},
"authQueryTemplate" : {
"params" : {
"name" : "TemplateName",
"acds" : "ServiceAccessGroupList",
"result_url" : "RedirectURL"
},
"result" : {
"id" : "AuthQueryID",
"auth_url" : "RedirectURL"
},
"throws" : [
"SecurityError"
]
},
"startSession" : {
"params" : {
"start_token" : "SessionStartToken",
"client" : "ClientFingerprints"
},
"result" : {
"token" : "SessionToken",
"info" : "AuthInfo"
},
"throws" : [
"InvalidStartToken",
"PleaseReauth"
]
},
"resumeSession" : {
"params" : {
"start_token" : "SessionToken",
"client" : "ClientFingerprints"
},
"result" : "boolean",
"throws" : [
"UnknownSession",
"PleaseReauth"
]
},
"closeSession" : {
"params" : {
"start_token" : "SessionToken"
},
"result" : "boolean"
}
},
"requires" : [
"SecureChannel",
"MessageSignature"
]
}
{
"iface" : "futoin.info.me",
"version" : "{ver}",
"ftn3rev" : "1.8",
"imports" : [
"futoin.ping:1.0",
"futoin.auth.types:{ver}"
],
"funcs" : {
"getEmail" : {
"result" : "Email",
"throws" : [
"NoValidatedEmail"
]
},
"getPhone" : {
"result" : "Phone",
"throws" : [
"NoValidatedPhone"
]
},
"getNames" : {
"result" : {
"first" : "LatinName",
"middle" : "LatinFullName",
"last" : "LatinName",
"full" : "LatinFullName",
"n_first" : "NativeName",
"n_middle" : "NativeFullName",
"n_last" : "NativeName",
"n_full" : "NativeFullName"
},
"throws" : [
"NoValidatedNames"
]
},
"getAvatar" : {
"rawresult" : true
},
"getDateOfBirth" : {
"result" : "Datestamp"
},
"getPlaceOfBirth" : {
"result" : {
"place" : "LatinLocation",
"n_place" : "NativeLocation"
}
},
"getHomeAddress" : {
"result" : {
"country" : "ISO3166A3",
"address" : "LatinLocation",
"n_address" : "NativeLocation"
}
}
},
"requires" : [
"SecureChannel"
]
}
=END OF SPEC=