I'm trying to do basic authentication to view a protected url. I want to access the protected url which looks like this:
http://api.test.com/userinfo/vid?=1234
So I do the following with a WebView:
mWebView.setHttpAuthUsernamePassword("api.test.com", "", "me@test.com", "mypassword");
mWebView.loadUrl("http://api.test.com/userinfo/user?uid=53461");
but the authentication doesn't seem to work, I'm just getting an output error page. Am I using the WebView method correctly here?
Update: Trying with curl:
curl -u me@test.com:mypassword http://api.test.com/userinfo/user?uid=53461
and it pulls the page fine. I tried every combination of the host parameter, the owners of the api don't know what I mean by 'realm' though (and neither do I) - what info could I 开发者_Go百科give them to help this along?
Thanks
Another option is to use a WebViewClient;
webview.setWebViewClient(new MyWebViewClient ());
private class MyWebViewClient extends WebViewClient {
@Override
public void onReceivedHttpAuthRequest(WebView view,
HttpAuthHandler handler, String host, String realm) {
handler.proceed("me@test.com", "mypassword");
}
}
webview.setWebViewClient(new WebViewClient () {
public void onReceivedHttpAuthRequest(WebView view,
HttpAuthHandler handler, String host, String realm) {
handler.proceed("login", "pass");
}
});
The default behavior of a WebView is to discard all authentication requests. Even if setHttpAuthUsernamePassword.
You have to set a WebViewClient and Override the method onReceivedHttpAuthRequest
If you do not mind writing your username and password into the url, then it is not necessary to change your webview client.
Just open the following url in the webview:
http://username:password@api.test.com/userinfo/vid?=1234
In this example realm is By Invitation Only
AuthType Basic
AuthName "By Invitation Only"
AuthUserFile /usr/local/apache/passwd/passwords
Require user rbowen sungo
You may need something other than ""
for the second parameter. Contact the developer of the Web site and find out what an appropriate realm should be. Or, use tools like curl
to find out what the realm should be.
I never did get setHttpAuthUsernamePassword to work with phonegap's FileTransfer.download (since it doesn't use the webview), but I DID get this to work with phonegap. It's worth noting if any other phonegap people end up on this thread.
Authenticator.setDefault(new Authenticator() {
protected PasswordAuthentication getPasswordAuthentication() {
return new PasswordAuthentication(user, pass.toCharArray());
}
});
This is so silly. I hacked something together that worked for me, I hope it'll work for you too.
public class AuthRequestDialogFragment extends DialogFragment
{
@InjectView(R.id.dauth_userinput)
public EditText userinput;
@InjectView(R.id.dauth_passinput)
public EditText passinput;
@OnClick(R.id.dauth_login)
public void login(View view) {
((Callback) getTargetFragment()).login(userinput.getText().toString(), passinput.getText().toString());
this.dismiss();
}
@OnClick(R.id.dauth_cancel)
public void cancel(View view) {
((Callback) getTargetFragment()).cancel();
this.dismiss();
}
public static interface Callback
{
public void login(String username, String password);
public void cancel();
}
@Override
public void onStart() {
super.onStart();
WindowManager wm = (WindowManager) getActivity().getSystemService(Context.WINDOW_SERVICE);
Display display = wm.getDefaultDisplay();
int width = display.getWidth();
int height = display.getHeight();
getDialog().getWindow().setLayout(width*2/3, height/5*2);
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState)
{
View view = inflater.inflate(R.layout.dialog_authrequest, container);
ButterKnife.inject(this, view);
getDialog().setTitle("Authorization required");
return view;
}
}
And
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="wrap_content"
android:layout_height="wrap_content">
<TextView
android:id="@+id/dauth_requsertext"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="The server requires a username and password."
android:layout_alignParentTop="true"
android:layout_alignParentStart="true"
android:layout_alignParentLeft="true"
android:layout_marginLeft="15dp"
android:layout_marginStart="15dp"
android:layout_marginTop="15dp"/>
<RelativeLayout
android:id="@+id/dauth_centercontainer"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerInParent="true">
<TextView
android:id="@+id/dauth_usertext"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Username"
android:layout_alignParentTop="true"
android:layout_alignParentStart="true"
android:layout_alignParentLeft="true"
android:layout_marginLeft="15dp"
android:layout_marginStart="15dp"
android:layout_marginTop="15dp"/>
<TextView
android:id="@+id/dauth_passtext"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="20dp"
android:text="Password"
android:layout_below="@+id/dauth_usertext"
android:layout_alignLeft="@+id/dauth_usertext"
android:layout_alignStart="@+id/dauth_usertext"/>
<EditText
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/dauth_userinput"
android:ems="12"
android:layout_alignBottom="@+id/dauth_usertext"
android:layout_toRightOf="@id/dauth_usertext"
android:layout_toEndOf="@id/dauth_usertext"/>
<EditText
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/dauth_passinput"
android:layout_marginTop="20dp"
android:inputType="textPassword"
android:ems="12"
android:layout_alignBottom="@+id/dauth_passtext"
android:layout_toRightOf="@id/dauth_passtext"
android:layout_toEndOf="@id/dauth_passtext"
android:layout_alignLeft="@id/dauth_userinput"
android:layout_alignStart="@id/dauth_userinput"/>
</RelativeLayout>
<Button
android:id="@+id/dauth_cancel"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Cancel"
android:layout_alignParentBottom="true"
android:layout_alignParentRight="true"
android:layout_alignParentEnd="true"
android:layout_marginBottom="15dp"
android:layout_marginRight="15dp"
android:layout_marginEnd="15dp"/>
<Button
android:id="@+id/dauth_login"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Log In"
android:layout_alignTop="@+id/dauth_cancel"
android:layout_marginRight="15dp"
android:layout_marginEnd="15dp"
android:layout_toLeftOf="@+id/dauth_cancel"/>
</RelativeLayout>
And
public class WebViewFragment extends Fragment implements AuthRequestDialogFragment.Callback {
@Override
public void login(String username, String password) {
Log.d(this.getClass().getName(), "Login");
myWebViewClient.login(username, password);
}
@Override
public void cancel() {
Log.d(this.getClass().getName(), "Cancel");
myWebViewClient.cancel();
}
And the most important:
private class MyWebViewClient extends WebViewClient {
private WebView myView;
private HttpAuthHandler httpAuthHandler;
private String host;
private String realm;
@Override
public void onReceivedHttpAuthRequest(WebView view, HttpAuthHandler handler, String host, String realm) {
AuthRequestDialogFragment authRequestDialogFragment = new AuthRequestDialogFragment();
FragmentManager fragmentManager = ((getActivity()).getSupportFragmentManager());
authRequestDialogFragment.setTargetFragment(WebViewFragment.this, 0);
authRequestDialogFragment.show(fragmentManager, "dialog");
this.httpAuthHandler = handler;
this.myView = view;
this.host = host;
this.realm = realm;
}
public void login(String username, String password) {
httpAuthHandler.proceed(username, password);
myView = null;
httpAuthHandler = null;
host = null;
realm = null;
}
public void cancel() {
super.onReceivedHttpAuthRequest(myView, httpAuthHandler, host, realm);
myView = null;
httpAuthHandler = null;
host = null;
realm = null;
}
}
Uses dependency:
compile 'com.jakewharton:butterknife:6.0.0'
精彩评论