/** @file mv_tokenauth.sas @brief Get initial Refresh and Access Tokens @details Before a Refresh Token can be obtained, the client must be registered by an administrator. This can be done using the `mv_registerclient` macro, after which the user must visit a URL to get an additional code (if using oauth). That code (or username / password) is used here to get the Refresh Token (and an initial Access Token). THIS MACRO CAN ONLY BE USED ONCE - further access tokens can be obtained using the `mv_gettokenrefresh` macro. Access tokens expire frequently (every 10 hours or so) whilst refresh tokens expire periodically (every month or so). This is all configurable. Usage: filename mc url "https://raw.githubusercontent.com/sasjs/core/main/all.sas"; %inc mc; %mv_registerclient(outds=clientinfo) %mv_tokenauth(inds=clientinfo,code=LD39EpalOf) A great article for explaining all these steps is available here: https://blogs.sas.com/content/sgf/2019/01/25/authentication-to-sas-viya/ @param inds= A dataset containing client_id, client_secret, and auth_code @param outds= A dataset containing access_token and refresh_token @param client_id= The client name @param client_secret= client secret @param grant_type= valid values are "password" or "authorization_code" (unquoted). The default is authorization_code. @param code= If grant_type=authorization_code then provide the necessary code here @param user= If grant_type=password then provide the username here @param pass= If grant_type=password then provide the password here @param access_token_var= The global macro variable to contain the access token @param refresh_token_var= The global macro variable to contain the refresh token @param base_uri= The Viya API server location @version VIYA V.03.04 @author Allan Bowe, source: https://github.com/sasjs/core

SAS Macros

@li mp_abort.sas @li mf_getplatform.sas @li mf_getuniquefileref.sas @li mf_getuniquelibref.sas @li mf_existds.sas **/ %macro mv_tokenauth(inds=mv_registerclient ,outds=mv_tokenauth ,client_id=someclient ,client_secret=somesecret ,grant_type=authorization_code ,code= ,user= ,pass= ,access_token_var=ACCESS_TOKEN ,refresh_token_var=REFRESH_TOKEN ,base_uri=#NOTSET# ); %global &access_token_var &refresh_token_var; %local fref1 fref2 libref; /* test the validity of inputs */ %mp_abort(iftrue=(&grant_type ne authorization_code and &grant_type ne password) ,mac=&sysmacroname ,msg=%str(Invalid value for grant_type: &grant_type) ) %if %mf_existds(&inds) %then %do; data _null_; set &inds; call symputx('client_id',client_id,'l'); call symputx('client_secret',client_secret,'l'); if not missing(auth_code) then call symputx('code',auth_code,'l'); run; %end; %mp_abort(iftrue=(&grant_type=authorization_code and %str(&code)=%str()) ,mac=&sysmacroname ,msg=%str(Authorization code required) ) %mp_abort(iftrue=( &grant_type=password and (%str(&user)=%str() or %str(&pass)=%str())) ,mac=&sysmacroname ,msg=%str(username / password required) ) /* prepare appropriate grant type */ %let fref1=%mf_getuniquefileref(); data _null_; file &fref1; if "&grant_type"='authorization_code' then string=cats( 'grant_type=authorization_code&code=',symget('code')); else string=cats('grant_type=password&username=',symget('user') ,'&password=',symget(pass)); call symputx('grantstring',cats("'",string,"'")); run; /*data _null_;infile &fref1;input;put _infile_;run;*/ /** * Request access token */ %if &base_uri=#NOTSET# %then %let base_uri=%mf_getplatform(VIYARESTAPI); %let fref2=%mf_getuniquefileref(); proc http method='POST' in=&grantstring out=&fref2 url="&base_uri/SASLogon/oauth/token" WEBUSERNAME="&client_id" WEBPASSWORD="&client_secret" AUTH_BASIC; headers "Accept"="application/json" "Content-Type"="application/x-www-form-urlencoded"; run; /*data _null_;infile &fref2;input;put _infile_;run;*/ /** * Extract access / refresh tokens */ %let libref=%mf_getuniquelibref(); libname &libref JSON fileref=&fref2; /* extract the tokens */ data &outds; set &libref..root; call symputx("&access_token_var",access_token); call symputx("&refresh_token_var",refresh_token); run; libname &libref clear; filename &fref1 clear; filename &fref2 clear; %mend mv_tokenauth;