Reputation: 1
I want to connect my scim api to okta for user provisioning. Not able to integate scim API with okta. Also not aware of the steps to do the integration. Any help would be highly appreciated.
I am providing the scim api code which i am going to integrate with okta.
UserController
using System.Net;
using System.Security.Principal;
using System.Text;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Newtonsoft.Json.Linq;
using ScimConnector1.Models;
using System.Threading;
using System.Net;
using System.Collections.Generic;
using System.Text.RegularExpressions;
using ScimConnector1.BasicAuth;
using Group = ScimConnector1.Models.Group;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
using static System.Net.Mime.MediaTypeNames;
using System.Net.Http.Formatting;
namespace ScimConnector1.Controllers
{
[Authorize]
[Route("scim/v2/[controller]")]
[ApiController]
//[BasicAuthentication]
public class UsersController : ControllerBase
{
ScimApi scimApi = new ScimApi();
//Create User
[HttpPost]
public HttpResponseMessage PostUser([FromBody] User userObject)
{
// Map the SCIM user to a local user object
var user = new User
{
id = userObject.id,
userName = userObject.userName,
name =new Name
{
givenName = userObject.name.givenName,
familyName = userObject.name.familyName,
},
emails = userObject.emails,
};
try
{
scimApi.AddUserToStore(user);
}
catch (Exception ex)
{
// Handle any errors that occur during user creation
return new HttpResponseMessage(HttpStatusCode.InternalServerError)
{
Content = new StringContent(ex.Message),
ReasonPhrase = "Error while creating user"
};
}
// Return the SCIM representation of the created user
var createdScimUser = new User
{
id = user.id,
userName = user.userName,
name=new Name
{
givenName = user.name.givenName,
familyName = user.name.familyName,
},
emails = user.emails,
};
var response = new HttpResponseMessage(HttpStatusCode.Created)
{
Content = new ObjectContent<User>(createdScimUser, new JsonMediaTypeFormatter()),
};
response.Headers.Location = new Uri($"{Request.Scheme}://{Request.Host}/Groups/{createdScimUser.userName}");
return response;
}
//Get User
[HttpGet]
public IActionResult GetUser(string id)
{
// get user from your application here
User existingUser = scimApi.GetUserById(id);
// if user is not found in application, return 404
if (existingUser == null)
{
return NotFound();
}
else
{
return Ok(existingUser);
}
}
//Put user[update user]
[HttpPut]
public IActionResult UpdateUser(string id, [FromBody] User user)
{
// Implement your logic for updating a user by ID
User existingUser = scimApi.GetUserById(id);
if (existingUser == null)
{
return NotFound();
}
//existingUser.id = user.id;
existingUser.userName = user.userName;
existingUser.name = new Name
{
givenName = user.name.givenName,
familyName = user.name.familyName
};
existingUser.emails = user.emails;
// Update the user in your database or external system
scimApi.UpdateUserInDb
(existingUser.id, existingUser.userName, existingUser.name.familyName, existingUser.name.givenName, existingUser.emails);
return Ok(existingUser);
//return Ok(user);
}
}
}
GroupController
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using ScimConnector1.Models;
using System.Net;
namespace ScimConnector1.Controllers
{
[Authorize]
[Route("scim/v2/[controller]")]
[ApiController]
public class GroupsController : ControllerBase
{
ScimApi scimApi = new ScimApi();
[HttpPost] //create Group
public IActionResult CreateGroup([FromBody] Group scimGroup)
{
// Map the SCIM group to a local Group object
var group = new Group
{
//Id = scimGroup.ExternalId,
DisplayName = scimGroup.DisplayName,
Description = scimGroup.Description,
//Members = scimGroup.Members.Select(m => m.id).ToList()
//Members = new List<string>()
};
// Create the group in the database using the local group object
try
{
scimApi.CreateGroupInDb(group);
}
catch (Exception ex)
{
// Handle any errors that occur during group creation
return StatusCode(500, ex.Message);
}
// Return the SCIM representation of the created group
var createdScimGroup = new Group
{
//Id = group.Id,
//ExternalId = group.Id,
DisplayName = group.DisplayName,
Description = group.Description,
//Members = scimGroup.Members.Select(m => new User { id = m}).ToList()
};
return Created($"{Request.Scheme}://{Request.Host}/Groups/{createdScimGroup.DisplayName}", createdScimGroup);
}
[HttpGet] //get Group
public HttpResponseMessage GetGroup(HttpRequestMessage request, string id)
{
Group existingGroup = scimApi.GetGroupById(id);
// get group from app
if (existingGroup != null)
{
return request.CreateResponse(HttpStatusCode.OK, existingGroup);
}
else
{
return request.CreateResponse(HttpStatusCode.NotFound);
}
}
[HttpPut] //update Group
public IActionResult PutGroup(String id, Group group)
{
// update group in app
Group existingGroup = scimApi.GetGroupById(id);
if (existingGroup == null)
{
return NotFound();
}
//existingUser.id = user.id;
existingGroup.DisplayName = group.DisplayName;
existingGroup.Description = group.Description;
// Update the user in your database or external system
scimApi.UpdateGroupInDb(id, existingGroup.DisplayName, existingGroup.Description);
return Ok(existingGroup);
}
}
}
ScimApi.cs: where all the methods which is called by the controllers are present
using System.Data;
using System.Data.SqlClient;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using Npgsql;
namespace ScimConnector1.Models
{
public class ScimApi
{
public string connectionString = "Port=XXXXX; Host=XXXXXXXX; Database=XXXXX;User Id=XXXXX;Password=XXXXX;";
public void AddUserToStore(User user)
{
// Add the user to your app's user store
// create a new database connection using the provided connection string
using (var conn = new
NpgsqlConnection(connectionString))
{
// open the database connection
conn.Open();
var command = new NpgsqlCommand("INSERT INTO Users (Id, UserName, FirstName, LastName, Email) " +
"VALUES (@Id, @UserName, @FirstName, @LastName, @Email)", conn);
command.Parameters.AddWithValue("@Id", user.id);
command.Parameters.AddWithValue("@UserName", user.userName);
command.Parameters.AddWithValue("@FirstName", user.name.givenName);
command.Parameters.AddWithValue("@LastName", user.name.familyName);
command.Parameters.AddWithValue("@Email", user.emails);
int rowsAffected = command.ExecuteNonQuery();
if (rowsAffected != 1)
{
throw new Exception($"Failed to insert user with id {user.id} into database.");
}
}
}
public User GetUserById(string id)
{
User user = null;
using (NpgsqlConnection connection = new NpgsqlConnection(connectionString))
{
connection.Open();
using (NpgsqlCommand command = new NpgsqlCommand("SELECT * FROM users WHERE id = @id", connection))
{
command.Parameters.Add(new NpgsqlParameter("id", DbType.String)).Value = id;
using (NpgsqlDataReader reader = command.ExecuteReader())
{
if (reader.Read())
{
user = new User
{
id = reader.GetString(reader.GetOrdinal("id")),
userName = reader.GetString(reader.GetOrdinal("username")),
name=new Name
{
givenName = reader.GetString(reader.GetOrdinal("firstName")),
familyName = reader.GetString(reader.GetOrdinal("lastName")),
},
emails = reader.GetString(reader.GetOrdinal("email"))
};
}
}
}
}
return user;
}
public void UpdateUserInDb(string id, string userName, string firstName, string lastName, string email)
{
using (NpgsqlConnection connection = new NpgsqlConnection(connectionString))
{
connection.Open();
using (NpgsqlCommand command = new NpgsqlCommand("UPDATE users SET username=@userName, firstName = @firstName, lastName = @lastName, email = @email WHERE id = @id", connection))
{
command.Parameters.AddWithValue("@id", id);
command.Parameters.AddWithValue("@username", userName);
command.Parameters.AddWithValue("@firstName", firstName);
command.Parameters.AddWithValue("@lastName", lastName);
command.Parameters.AddWithValue("@email", email);
command.ExecuteNonQuery();
}
}
}
public Group GetGroupById(string id)
{
Group group = null;
using (NpgsqlConnection connection = new NpgsqlConnection(connectionString))
{
connection.Open();
using (NpgsqlCommand command = new NpgsqlCommand("SELECT * FROM groups WHERE id = @id", connection))
{
command.Parameters.Add(new NpgsqlParameter("id", DbType.String)).Value = id;
using (NpgsqlDataReader reader = command.ExecuteReader())
{
if (reader.Read())
{
group = new Group
{
//id = reader.GetString(reader.GetOrdinal("id")),
DisplayName = reader.GetString(reader.GetOrdinal("displayname")),
Description = reader.GetString(reader.GetOrdinal("description")),
};
}
}
}
}
return group;
}
public void UpdateGroupInDb(string id ,string DisplayName,string Discription)
{
using (NpgsqlConnection connection = new NpgsqlConnection(connectionString))
{
connection.Open();
using (NpgsqlCommand command = new NpgsqlCommand("UPDATE groups SET DisplayName=@displayName, description= @Description WHERE id = @id", connection))
{
//command.Parameters.AddWithValue("@id", id);
command.Parameters.AddWithValue("@DisplayName", DisplayName);
command.Parameters.AddWithValue("@Description", Discription);
command.ExecuteNonQuery();
}
}
}
public void CreateGroupInDb(Group group)
{
//string connectionStringToGroup = "Server=TestServer;Port=2001; Host=127.0.0.1; Database=groups;User Id=Drona;Password=12345;";
using (var connection = new NpgsqlConnection(connectionString))
{
connection.Open();
using (var command = new NpgsqlCommand("INSERT INTO groups (displayname,discription) VALUES (@displayName,@discription)", connection))
{
//command.Parameters.AddWithValue("id", group.Id);
command.Parameters.AddWithValue("displayName", group.DisplayName);
command.Parameters.AddWithValue("discription", group.Description);
//command.Parameters.AddWithValue("members", JsonConvert.SerializeObject(group.Members));
command.ExecuteNonQuery();
}
connection.Close();
}
}
}
}
This is the scim API code that I am using to integrate with okta. here I want my scim API to transfer data from okta to my app( ryt now its the database). Also hosted the above code in azure. please let me know the proper way now to integrate the above scim API code with okta. I am using basic authentication in the scim API.
![1]: https://i.sstatic.net/4QVKv.png
This image is of the okta platform, the app in okta is scim api test app(basic auth).
In the image where I have given the base URL of my scim api with the authentication credential.When I click "Test api credential" I am getting the error as "Error authenticating: Bad Request. Errors reported by the remote server:"(as in the image).
Please let me know the changes to be done in my api or let me know the proper steps to be followed for scim integration.
Upvotes: 0
Views: 424