I want to achieve microfrontend architecture using Apache Wicket but I cannot make it work.
add(new WebMarkupContainer("testFrame") {
#Override
protected void onComponentTag(ComponentTag tag) {
checkComponentTag(tag, "iframe");
super.onComponentTag(tag);
//Won't work like this if you want to send credentials.
//tag.put("src", "http://localhost:8089/httpBasicAuthenticated/url/page/");
}
#Override
public void onComponentTagBody(MarkupStream markupStream, ComponentTag openTag) {
Response response = getRequestCycle().getResponse();
final CredentialsProvider provider = new BasicCredentialsProvider();
String username = "user";
String password = "password";
final UsernamePasswordCredentials credentials = new UsernamePasswordCredentials(username, password);
provider.setCredentials(AuthScope.ANY, credentials);
final HttpClient client = HttpClientBuilder.create().setDefaultCredentialsProvider(provider).build();
HttpResponse httpResponse = null;
String body = "";
try {
httpResponse = client.execute(new
HttpGet("http://localhost:8089/httpBasicAuthenticated/url/page/"));
body = IOUtils.toString(httpResponse.getEntity().getContent(), "UTF-8");
} catch (final IOException e) {
e.printStackTrace();
}
response.write(body);
}
});
Result from inspecting the element
I am trying out with an iframe but it's not rendering the page inside the iframe. Is there something wrong? How would I send the credentials on request of the page through iframe?
EDIT:
In this code, I'm trying to send the credentials automatically so that the authentication prompt doesn't show.
With basic authentication you need to render <iframe src="..."></iframe> and the browser will show you a dialog to enter the credentials.
If you construct the body at the server (i.e. in Wicket code) then you don't need an iframe, but a div.
Related
I want to access data on the openrouteservice API - specifically the distance between two given coordinates on the globe - from my Android application.
I have made requests and gotten viable responses from another API that converts two given addresses into their latlong coordinates using the same style of code this request is trying to execute. It works fine, the coordinates arrive and i can further utilize them no problem.
My problem is that i seem to be accessing the API wrongly because if I Log the URL as seen below and copy it from the Debug window into my browser it sends the request, gets a response and shows it in the browser window.
But my application doesn't recieve a response from the API as the onResponse code bit is never executed and the "Fetch done" Log never appears in the actual Debug Log.
The following is my setup of code, which uses Volley to access HTTP Requests and which works fine for other APIs.
#Override
protected String doInBackground(String... strings) {
Log.d("Run =>","Query 3");
String targetKoordURL = null;
String startKoordURL = null;
try {
startKoordURL = startK.getString("lon").concat(",").concat(startK.getString("lat"));
targetKoordURL = targetK.getString("lon").concat(",").concat(targetK.getString("lat"));
} catch (JSONException e) {
e.printStackTrace();
}
String URLfin = "https://api.openrouteservice.org/v2/directions/driving-car?api_key=5b3ce3597851110001cf624823e587e7a80c4c6ab02af6d394585213&start="+startKoordURL+"&end="+targetKoordURL;
Log.d("Debug =>", URLfin);
JsonObjectRequest req = new JsonObjectRequest(Request.Method.GET, URLfin, null, new Response.Listener<JSONObject>() {
#Override
public void onResponse(JSONObject response) {
store = response;
Log.d("Run =>", "Fetch done!");
continueImp();
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
if(error instanceof TimeoutError || error instanceof NoConnectionError){
sideFetcherHTTPRequestStart replace = new sideFetcherHTTPRequestStart();
replace.execute();
Log.d("VOLLEY_ERROR", "Retrying on Kilometer request");
}
error.printStackTrace();
}
}){
#Override
public Map<String, String> getHeaders() throws AuthFailureError {
Map<String, String> params = new HashMap<String, String>();
params.put("Accept", "application/json,application/geo+json,application/gpx+xml,img/png; charset=utf-8");
return params;
}
};
return null;
}
You forget to add the request to request queue, try to do as following:
// Instantiate the RequestQueue.
RequestQueue queue = Volley.newRequestQueue(this);
JsonObjectRequest req = new JsonObjectRequest(/*params*/);
//add above request to queue
queue.add(req);
I'm calling ResetPassword action from an Email (ASP.NET MVC 5).
http://localhost:34162/Account/ResetPassword?code=BwEA181bAECFMcn1vwPdrctS/wcyncKPxGT9Zx1tDuPwKGpe9H1W7LI3Zm9fM+3aA5Fok5GhLPBHqbtiGfpL8Cmdx7RNC6RJ7d6t9ZgFBwgwYk3zssU1Nh64PWHJAabVG9Wv9VWDNdj+Fz0UA712XA==
This is the address in my Browser.
However, in debug I receive this string in the ResetPassword Action:
// GET: /Account/ResetPassword
[AllowAnonymous]
public ActionResult ResetPassword(string code)
{
return code == null ? View("Error") : View();
}
The 'code' is:
BwEA181bAECFMcn1vwPdrctS/wcyncKPxGT9Zx1tDuPwKGpe9H1W7LI3Zm9fM 3aA5Fok5GhLPBHqbtiGfpL8Cmdx7RNC6RJ7d6t9ZgFBwgwYk3zssU1Nh64PWHJAabVG9Wv9VWDNdj Fz0UA712XA==
i.e., it is not url-encoded and of course password is not reset with invalid token message.
What can I do for getting the right string in the Action?
You can encode the string in the following way:
[AllowAnonymous]
public ActionResult ResetPassword(string code)
{
code = Server.HtmlEncode(code);
}
Fore more information on how to encode you can look at
https://msdn.microsoft.com/en-us/library/w3te6wfz(v=vs.110).aspx
I still don't know what was the problem. Looks like it shouldn't have worked in the first place. I wish I knew why Microsoft feel the need to use tokens with slashes and pluses.
Anyway, I just Base64 encoded and decoded the token as follows:
before sending the Email to the user:
...
string code = await UserManager.GeneratePasswordResetTokenAsync(user.Id);
code = CommonFuncs.Base64Encode(code);
EmailsBL.PasswordResetEmail(model.Email, code); <-- emailing the link for password rest to the user
And then when receiving:
// POST: /Account/ResetPassword
[HttpPost]
[AllowAnonymous]
[ValidateAntiForgeryToken]
public async Task<ActionResult> ResetPassword(ResetPasswordViewModel model)
{
/////////////////////////////////////////////////////////////////////
// NOTE: if email is not CONFIRMED then reset password silently fails
////////////////////////////////////////////////////////////////////
if (!ModelState.IsValid)
{
return View(model);
}
model.Code = CommonFuncs.Base64Decode(model.Code);
i.e., decoding the token.
This following is just for completeness:
public static string Base64Encode(string plainText)
{
string base64string = null;
if (plainText != null)
{
var plainTextBytes = System.Text.Encoding.UTF8.GetBytes(plainText);
base64string = System.Convert.ToBase64String(plainTextBytes);
}
return base64string;
}
public static string Base64Decode(string base64EncodedData)
{
string decodedBase64String = null;
if (base64EncodedData != null)
{
var base64EncodedBytes = System.Convert.FromBase64String(base64EncodedData);
decodedBase64String = System.Text.Encoding.UTF8.GetString(base64EncodedBytes);
}
return decodedBase64String;
}
Loving Azure AD B2C... Looking forward to when it is out of preview!!!
Have a special case I need help putting my head around.
I have a page where I capture new email addresses via a web form.
After adding that email to my mailing list, I want to then create an AD B2C account automatically without making the user click any additional buttons using my ASP.NET MVC Site.
In reading the Article at: https://azure.microsoft.com/en-us/documentation/articles/active-directory-b2c-devquickstarts-graph-dotnet/
I see that it is possible to add a new user using the Graph API.
However, this example is written using a cmd program.
Does anyone know if there is some sample code to allow me to insert a user into AD B2C inside an MVC controller?
Heres some sample code on how I do it from ASP.Net MVC. Remeber that you need to include ClientId and Clientsecret (they are separate from the ASP.Net webapp) as explained in the article you mention. Code from controller--helperclass:
UserController:
// POST: User/Create
[HttpPost]
public async Task<ActionResult> Create(b2cuser usr)
{
try
{
usr.AlternativeSignInNamesInfo.First().Value = string.Format("{0}_{1}", usr.FirstName, usr.LastName);
usr.DisplayName = string.Format("{0} {1}", usr.FirstName, usr.LastName);
string json = Newtonsoft.Json.JsonConvert.SerializeObject(usr, Formatting.None);
Utils.GraphAPIHelper api = new Utils.GraphAPIHelper(graphAPIClientId, graphAPIClientSecret, tenant);
string res = await api.GraphPostRequest("/users/", json);
return RedirectToAction("Index");
}
catch (Exception e)
{
return View();
}
}
And in the GraphAPIHelper:
internal async Task<string> GraphPostRequest(string api, string json)
{
AuthenticationResult result = authContext.AcquireToken(graphResourceID, credential);
HttpClient http = new HttpClient();
string url = aadGraphEndpoint + tenant + api + "?" + aadGraphVersion;
HttpRequestMessage request = new HttpRequestMessage(HttpMethod.Post, url);
request.Headers.Authorization = new AuthenticationHeaderValue("Bearer", result.AccessToken);
request.Content = new StringContent(json, Encoding.UTF8, "application/json");
HttpResponseMessage response = await http.SendAsync(request);
if (!response.IsSuccessStatusCode)
{
string error = await response.Content.ReadAsStringAsync();
object formatted = JsonConvert.DeserializeObject(error);
throw new WebException("Error Calling the Graph API: \n" + JsonConvert.SerializeObject(formatted, Formatting.Indented));
}
return await response.Content.ReadAsStringAsync();
}
And finally, some samplecode from the model, pls note JsonProperty(Order:
public class b2cuser
{
[JsonProperty(Order = 0, PropertyName = "accountEnabled")]
public bool AccountEnabled = true;
[JsonProperty(Order = 1, PropertyName = "alternativeSignInNamesInfo")]
public List<AlternativeSignInNamesInfo> AlternativeSignInNamesInfo { get; set; }
[JsonProperty(Order = 2, PropertyName = "creationType")]
public string CreationType = "NameCoexistence";
the code tries to download text from a php script via a http request. Since the code should run on a Raspberry Pi with Windows IoT I have to use GetResponseAsync(). It works fine if I use it without the credentials (Http source is public then). When I add the NetworkCredential stuff I get the exception you see in the picture.
Screenshot
In the end I want to be able to load data from a http website that is protected via .htaccess. I hope anyone has some experience with this!
namespace HttpGetBeisp1Hta {
public sealed partial class MainPage : Page {
public MainPage() {
InitializeComponent();
}
private async void ClickMe_Click(object sender, RoutedEventArgs e)
{
try {
await HoleDaten();
}
catch(Exception ex) {
textBlock.Text = ex.ToString();
}
}
private async Task HoleDaten() {
NetworkCredential myCred = new NetworkCredential("user", "pw");
CredentialCache myCache = new CredentialCache();
myCache.Add(new Uri("https://..'my secret uri'../getSave.php"), "Basic", myCred);
WebRequest request = WebRequest.Create("https://..'my secret uri'../getSave.php");
request.Credentials = myCache;
WebResponse response = await request.GetResponseAsync();
Stream dataStream = response.GetResponseStream();
StreamReader reader = new StreamReader(dataStream);
string responseFromServer = reader.ReadToEnd();
textBlock.Text = responseFromServer;
}
}
}
Found it out!
I modified the header manually. The username and pw needs to be added in base64. Use a converter and feed it with "Hans:Mueller" gets you:
private async Task HoleDaten() {
WebRequest request = WebRequest.Create("https:// ... ll.php");
request.Headers["Authorization"] = "Basic SGFuczpNdWVsbGVy";
WebResponse response = await request.GetResponseAsync();
Stream dataStream = response.GetResponseStream();
StreamReader reader = new StreamReader(dataStream);
string responseFromServer = reader.ReadToEnd();
textBlock.Text = responseFromServer;
}
I've done a custom Autologin Filter which seems to works well, but when Liferay redirects to the main page (once the user has been authenticated), the login portlet shows an error that I cannot understand.
The error shows "Your request failed to complete", but the user has been successfully logged and if I press F5 or navigate through the page, the error disappear.
My Autologin class implementation is:
public String[] login(HttpServletRequest request,
HttpServletResponse response) throws AutoLoginException {
String[] credentials = new String[3];
String p_id = request.getParameter("p_p_id");
String userName = null;
String password = null;
if (p_id != null) {
userName = request.getParameter("_" + p_id + "_login");
password = request.getParameter("_" + p_id + "_password");
//Custom authentication code required [...]
}
if (userName != null) {
// New Login
try {
//We log as Test user...just for TEST
long companyId = PortalUtil.getCompanyId(request);
User user = UserLocalServiceUtil.getUserByScreenName(companyId, "Test");
long userId = user.getUserId();
String userPwd = user.getPassword();
credentials[0] = Long.toString(userId);
credentials[1] = userPwd;
credentials[2] = Boolean.FALSE.toString();
} catch (Exception e) {
e.printStackTrace();
throw new AutoLoginException(e);
}
return credentials;
}
return credentials;
}
I've also implemented a Custom Authenticator which always return SUCCESS.
Do you have any idea about what I'm doing wrong?
Thank you very much in advance!
Ivan fontanals