There are several ways to do what I think you ask, I thought (and wrote) several different potential solutions, however the one that I share here is what I think is in the “to existing solutions using ASP.NET Membership / Role Provider Hope I have given you enough information to do what you need to do, but you can always comment and ask more questions if something is still unclear.
In your problem, do you describe the use of an ASP.NET web application that contains a WCF service for existing clients, but you want to extend it to use Android (java) queries? Given that the ASP.NET membership provider uses a lot of “behind the scenes” SOAP exchanges (for authentication, authorization, and encryption) that seem to be built into service framework standards, it would be a pretty big task to write a Java implementation ...
So, I wrote you an example of what will be integrated with the same "backend" provider, but it will also allow sending SOAP requests from any client without the need for a service link (I tested it using SoapUI , for example) ... I wrote your solution in C # (just like the WCF samples were written), however, you can very easily use the code converter to switch it to VB.NET . I also did not provide you with a method for encrypting and decrypting passwords, you will have to examine this bit yourself.
You will need to embed a new .svc file into your existing solution and create new entries in web.config (I assume that you know how to create a base HttpBinding and a service endpoint already).
You will also need to duplicate method calls (or instead create a new class with the contents of the method and reference it from where you implement the ServiceContract methods) and remove the [PrincipalPermission (SecurityAction) attributes and add the examples below to the new service. for example (using methods from Microsoft MemberhipAndRoleProvider WCF Sample ) -
// Allows all Users to call the Add method [PrincipalPermission(SecurityAction.Demand, Role = "Users")] public double Add(double n1, double n2) { double result = n1 + n2; return result; }
It would be:
// Allows all Users to call the Add method public double Add(double n1, double n2, string username, string token) { string isAuthorized = IsAuthorized(username, "Users", token) if (isAuthorized.Contains("Success") double result = n1 + n2; return result; else throw new Exception("Authorization Exception: " + isAuthorized); }
Here is my implementation (s) integrated into the Microsoft WCF Sample MembershipAndRoleProvider (download from here ):
IsolatedAuthService.svc
<%@ServiceHost Language="C#" Debug="true" Service="Microsoft.ServiceModel.Samples.IsolatedAuthService" CodeBehind="IsolatedAuthService.cs" %>
IIsolatedAuthService.cs
using System; using System.Collections.Generic; using System.Linq; using System.Runtime.Serialization; using System.ServiceModel; using System.Text; namespace Microsoft.ServiceModel.Samples {
IsolatedAuthService.cs
using System; using System.Collections.Generic; using System.Linq; using System.Runtime.Serialization; using System.ServiceModel; using System.Text; using System.Web; using System.Web.Hosting; using System.Web.Security; using System.Web.Configuration; using System.Configuration; using System.IO; using System.Security.Permissions; using System.Security.Principal; using System.ServiceModel.Activation; using System.Threading; namespace Microsoft.ServiceModel.Samples { public class IsolatedAuthService : IIsolatedAuthService { public string IsAuthorized(string username, string roleName, string token) { MembershipUser user = Membership.GetAllUsers()[username]; Configuration config = ConfigurationManager.OpenExeConfiguration(HostingEnvironment.MapPath("~") + "\\web.config"); SessionStateSection sessionStateConfig = (SessionStateSection)config.SectionGroups.Get("system.web").Sections.Get("sessionState"); InMemoryInstances instance = InMemoryInstances.Instance;
InMemoryInstances.cs
using System; using System.Collections.Generic; using System.Linq; using System.Text; namespace Microsoft.ServiceModel.Samples { public class InMemoryInstances { private static volatile InMemoryInstances instance; private static object syncRoot = new Object(); private Dictionary<string, string> usersAndTokens = null; private InMemoryInstances() { usersAndTokens = new Dictionary<string, string>(); } public static InMemoryInstances Instance { get { if (instance == null) { lock (syncRoot) { if (instance == null) instance = new InMemoryInstances(); } } return instance; } } public void addTokenUserPair(string username, string token) { usersAndTokens.Add(username, token); } public bool checkTokenUserPair(string username, string token) { if (usersAndTokens.ContainsKey(username)) { string value = usersAndTokens[username]; if (value.Equals(token)) return true; } return false; } public void removeTokenUserPair(string username) { usersAndTokens.Remove(username); } } }
Conditionally, this solution will not work if you balance the load on your WCF service on several servers (due to the instance class in memory), you can change the solution to use the database table instead of -memory if you need it.